无法从braced-init-list构造constexpr数组 [英] Cannot construct constexpr array from braced-init-list
问题描述
我已经实现了一个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屋!