本文介绍了无法从braced-init-list构造constexpr数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了一个constexpr数组,如下所示:

I've implemented a constexpr array like this:

template <typename T>
class const_array {
  const T* p;
  unsigned n;
public:
  template <unsigned N>
  constexpr const_array(const T(&a)[N]): p(a), n(N) { }

  constexpr unsigned size() const { return n; }
};

int main(int argc, char* argv[]) {
  // works
  static_assert(const_array<double>{{1.,2.,3.}}.size() == 3);

  // doesn't compile
  constexpr const_array<double> a{{1.,2.,3.}};
  static_assert(a.size() == 3);
}

为什么第一个static_assert会编译,但初始化a却失败?我使用的是gcc 6.2.0.我要

Why is it that the first static_assert compiles, but initializing a fails?I'm using gcc 6.2.0. I'm getting

: In function 'int main(int, char**)':
: error: 'const_array<double>{((const double*)(&<anonymous>)), 3u}' is not a constant expression
   constexpr const_array<double> a{{1.,2.,3.}};
                                        ^
test/const_array.cc:17:3: error: non-constant condition for static assertion
   static_assert(a.size() == 3);
   ^~~~~~~~~~~~~

推荐答案

编译器抱怨a.p的初始化程序不是常量表达式.失败了§5.20/5.2:

The compiler is complaining that the initializer of a.p is not a constant expression. It's failing §5.20/5.2:

换句话说,只有链接器已知的指针值才是有效常量. (此外,在您的示例中,指针悬空了.)

In other words, only pointer values known to the linker are valid constants. (Also, in your example the pointer is dangling.)

第一个static_assert不会触发此操作,因为p被丢弃并且n的值是一个常量表达式.常数表达式可能具有非常数子表达式.

The first static_assert doesn't trip this because p is discarded and the value of n is a constant expression. Constant expressions may have non-constant subexpressions.

这有效:

static constexpr double arr[] = { 1.,2.,3. };
constexpr const_array<double> a{ arr };
static_assert( a.size() == 3 );

使用@ Jarod42来指出评论中的问题.

Credit to @Jarod42 for pointing out the issue in the comments.

这篇关于无法从braced-init-list构造constexpr数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 20:07