这是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
和常量表达式同时一些文件,这种行为对我来说仍然没有任何意义。第一个例子如何被认为是一个有效的常量表达式,而不是第二个例子?我会欢迎任何解释,以便我可以在此后安息。
注:我会精确它的时候了,锵将无法编译第一个片段,因为它不执行该计划用于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有bug”? :)(不是说它有一个,只是一种可能性。)实际上,你应该可以通过编写你自己的类似物来测试这个,而不需要增加constexpr。另外,'constexpr std :: array b = {{a [0],a [1],a [2]}};'? –
Xeo
也许[this](http://ideone.com/56iP0Y)有助于缩小问题的范围 –
@Xeo无论我如何处理数组,似乎都可以正常工作(包括您的示例,而Andy只使用'std :: arrays' 'std :: initializer_list')。看起来问题只发生在编译时的'std :: initializer_list'。没有'constexpr'或'std :: array',我没有设法重现它。 – Morwenn