无法从braced-init-list构造constexpr数组 [英] Cannot construct constexpr array from braced-init-list

查看:125
本文介绍了无法从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:

如果该值是指针类型,则它包含具有静态存储持续时间的对象的地址,该对象末尾的地址(5.7),函数的地址或空指针值

if the value is of pointer type, it contains the address of an object with static storage duration, the address past the end of such an object (5.7), the address of a function, or a null pointer value

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

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数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆