【发布时间】:2013-04-17 10:29:40
【问题描述】:
这是this topic 的某种后续行动,涉及其中的一小部分。与上一个主题一样,让我们考虑一下我们的编译器具有用于std::initializer_list 和std::array 的constexpr 函数。现在,让我们直奔主题。
#include <array>
#include <initializer_list>
int main()
{
constexpr std::array<int, 3> a = {{ 1, 2, 3 }};
constexpr int a0 = a[0];
constexpr int a1 = a[1];
constexpr int a2 = a[2];
constexpr std::initializer_list<int> b = { a0, a1, a2 };
return 0;
}
#include <array>
#include <initializer_list>
int main()
{
constexpr std::array<int, 3> a = {{ 1, 2, 3 }};
constexpr std::initializer_list<int> b = { a[0], a[1], a[2] };
return 0;
}
它因这个错误而崩溃:
error: 'const std::initializer_list<int>{((const int*)(&<anonymous>)), 3u}' is not a constant expression
尽管我同时阅读了一些关于constexpr 和常量表达式的论文,但这种行为对我来说仍然没有任何意义。为什么第一个示例被认为是有效的常量表达式而不是第二个?我欢迎任何解释,以便我之后可以安息。
注意:我会马上准确地说,Clang 将无法编译第一个 sn-p,因为它没有实现为 C++14 计划的 constexpr 库添加.我使用的是 GCC 4.7。
编辑:好的,这里有一个重要的例子来说明什么被拒绝,什么不是:
#include <array>
#include <initializer_list>
constexpr int foo = 42;
constexpr int bar() { return foo; }
struct eggs { int a, b; };
int main()
{
constexpr std::array<int, 3> a = {{ 1, 2, 3 }};
constexpr int a0 = a[0];
constexpr int a1 = a[1];
constexpr int a2 = a[2];
// From Xeo and Andy tests
constexpr std::array<int, 1> a = { bar() }; // OK
constexpr std::array<int, 3> b = {{ a[0], a[1], a[2] }}; // OK
std::initializer_list<int> b = { a[0], a[1], a[2] }; // OK
constexpr std::initializer_list<int> b = { a0, a1, a2 }; // OK
constexpr std::initializer_list<int> b = { foo }; // OK
constexpr std::initializer_list<int> c = { bar() }; // ERROR
constexpr std::initializer_list<int> b = { a[0], a[1], a[2] }; // ERROR
// From Matheus Izvekov and Daniel Krügler
constexpr eggs good = { 1, 2 }; // OK
constexpr std::initializer_list<eggs> bad = { { 1, 2 }, { 3, 4 } }; // ERROR
constexpr std::initializer_list<eggs> bad2 = { good, good }; // ERROR
return 0;
}
【问题讨论】:
-
“GCC 有错误”怎么样? :) (不是说它有一个,只是一种可能性。)实际上,您应该能够通过编写自己的类似物来测试没有
constexpr添加的内容。另外,constexpr std::array<int, 3> b = {{ a[0], a[1], a[2] }};呢? -
也许this 有助于缩小问题范围
-
@Xeo 无论我对数组做什么似乎都可以正常工作(包括您的示例,以及只有
std::arrays而不是std::initializer_list的Andy 示例)。似乎问题只发生在编译时std::initializer_list。没有constexpr或std::array,我无法重现它。 -
@Xeo 所以,是的,我想相信这是一个 GCC 错误,但一般来说,我宁愿确定它不是来自我对语言的理解 :)
标签: c++ c++11 compile-time constexpr constant-expression