天道酬勤,学无止境

Error with constexpr(gcc) - error: a brace-enclosed initializer is not allowed here before '{' token

struct X {
constexpr static char a1[] = "hello"; // Okay
constexpr static const char* a2[] = {"hello"}; // Error
};

int main(){}

Compiling with gcc gives the error:

error: a brace-enclosed initializer is not allowed here before '{' token

Is this an illegal use of constexpr?

EDIT

I tried 3 different versions of gcc, and it compiled on the newest 4.7.0 I have (I just downloaded it, I'm using mingw-w64), so it looks to be a fixed bug (a link to the bug would be nice though!).

4.7.0 20120311 (prerelease) // Okay
4.6.4 20120305 (prerelease) // Error
4.7.0 20110829 (experimental) // Error

评论

This is a bug which has been fixed. I have confirmed that the code compiles with g++ 4.7.0 20120311 (prerelease).

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 为什么我不能在类中初始化非常量静态成员或静态数组?(Why can't I initialize non-const static member or static array in class?)
    问题 为什么我不能在类中初始化非常量static成员或static数组? class A { static const int a = 3; static int b = 3; static const int c[2] = { 1, 2 }; static int d[2] = { 1, 2 }; }; int main() { A a; return 0; } 编译器发出以下错误: g++ main.cpp main.cpp:4:17: error: ISO C++ forbids in-class initialization of non-const static member ‘b’ main.cpp:5:26: error: a brace-enclosed initializer is not allowed here before ‘{’ token main.cpp:5:33: error: invalid in-class initialization of static data member of non-integral type ‘const int [2]’ main.cpp:6:20: error: a brace-enclosed initializer is not allowed here before ‘{’ token main.cpp:6
  • Is it possible to pass data as initializer_list to std::array of structures?
    I have the following code. Basically I want to initialize a std::array of non-POD structs using aggregate initialization syntax. Both g++ 4.6 and 4.7 (latest weekly snapshot) fails to compile the code. #include <array> struct TheClass { int a1, a2; TheClass(int b1, int b2) : a1{b1}, a2{b2} {}; }; template<unsigned D> struct OtherClass { std::array<TheClass, D> a; OtherClass(std::array<TheClass, 2> b) : a{b} {}; }; int main() { OtherClass<2>{{ {1, 2}, {2, 3} }}; //tried a lot of options here } GCC errors: v.cpp: In function ‘int main()’: v.cpp:20:37: error: no matching function for call to
  • Can I initialize an array using the std::initializer_list instead of brace-enclosed initializer?
    Can I initialize an array using the std::initializer_list object instead of brace-enclosed initializer? As known, we can do this: http://en.cppreference.com/w/cpp/language/aggregate_initialization unsigned char b[5]{"abc"}; // equivalent to unsigned char b[5] = {'a', 'b', 'c', '\0', '\0'}; int ar[] = {1,2,3}; std::array<int, 3> std_ar2{ {1,2,3} }; // std::array is an aggregate std::array<int, 3> std_ar1 = {1, 2, 3}; But I can't initialize an array by std::initializer_list il;: http://ideone.com/f6aflX #include <iostream> #include <initializer_list> #include <array> int main() { int arr1[] = {
  • Calling an explicit constructor with a braced-init list: ambiguous or not?
    Consider the following: struct A { A(int, int) { } }; struct B { B(A ) { } // (1) explicit B(int, int ) { } // (2) }; int main() { B paren({1, 2}); // (3) B brace{1, 2}; // (4) } The construction of brace in (4) clearly and unambiguously calls (2). On clang, the construction of paren in (3) unambiguously calls (1) where as on gcc 5.2, it fails to compile with: main.cpp: In function 'int main()': main.cpp:11:19: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous B paren({1, 2}); ^ main.cpp:6:5: note: candidate: B::B(A) B(A ) { } ^ main.cpp:5:8: note: candidate
  • Calling an explicit constructor with a braced-init list: ambiguous or not?
    Consider the following: struct A { A(int, int) { } }; struct B { B(A ) { } // (1) explicit B(int, int ) { } // (2) }; int main() { B paren({1, 2}); // (3) B brace{1, 2}; // (4) } The construction of brace in (4) clearly and unambiguously calls (2). On clang, the construction of paren in (3) unambiguously calls (1) where as on gcc 5.2, it fails to compile with: main.cpp: In function 'int main()': main.cpp:11:19: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous B paren({1, 2}); ^ main.cpp:6:5: note: candidate: B::B(A) B(A ) { } ^ main.cpp:5:8: note: candidate
  • 是否可以使用有条件选择的字符串文字初始化字符数组?(Is it possible to initialise a character array with a conditionally selected string literal?)
    问题 我知道用字符串文字初始化char数组是完全可能的: char arr[] = "foo"; C++11 8.5.2/1 是这样说的: char数组(无论是普通char 、 signed char还是unsigned char )、 char16_t数组、 char32_t数组或wchar_t数组可以分别由窄字符文字、 char16_t字符串文字、 char32_t字符串文字或宽字符串文字初始化,或由括在大括号中的适当类型的字符串文字组成。 字符串文字值的连续字符初始化数组的元素。 ... 但是,您可以对条件表达式中的两个字符串字面量做同样的事情吗? 例如像这样: char arr[] = MY_BOOLEAN_MACRO() ? "foo" : "bar"; (其中MY_BOOLEAN_MACRO()扩展为1或0 )。 C++11 5.16(条件运算符)相关部分如下: 1 ... 第一个表达式根据上下文转换为bool (第 4 条)。 它被评估,如果它是true ,则条件表达式的结果是第二个表达式的值,否则是第三个表达式的值。 ... 4 如果第二个和第三个操作数是相同值类别的泛左值并具有相同类型,则结果属于该类型和值类别,如果第二个或第三个操作数是位域,则结果是位域,或如果两者都是位域。 请注意,文字的长度相同,因此它们都是const char[4]类型的左值。 GCC
  • 我可以使用 std::initializer_list 而不是大括号封闭的初始化程序来初始化数组吗?(Can I initialize an array using the std::initializer_list instead of brace-enclosed initializer?)
    问题 我可以使用std::initializer_list对象而不是大括号封闭的初始化程序来初始化数组吗? 众所周知,我们可以这样做:http://en.cppreference.com/w/cpp/language/aggregate_initialization unsigned char b[5]{"abc"}; // equivalent to unsigned char b[5] = {'a', 'b', 'c', '\0', '\0'}; int ar[] = {1,2,3}; std::array<int, 3> std_ar2{ {1,2,3} }; // std::array is an aggregate std::array<int, 3> std_ar1 = {1, 2, 3}; 但是我不能通过std::initializer_list il;初始化一个数组std::initializer_list il; : http://ideone.com/f6aflX #include <iostream> #include <initializer_list> #include <array> int main() { int arr1[] = { 1, 2, 3 }; // OK std::array<int, 3> arr2 = { 1, 2, 3 }; //
  • g++ (4.7.2) bug or feature, when initializing static arrays at compile-time?
    Okay, so I was trying to do something clever by initializing a bunch of constexpr static int const arrays at compile-time. Even though the runtime-performance is not at all governed by initializing these arrays, it seemed like a fun little exercise. I wrote a test-setup to see if it was possible, and I ended up being able to do this: struct Test { constexpr static int const array[10] = Array<int, 10, 0, Increment>::array; }; constexpr int const Test::array[10]; int main() { cout << Test::array[3] << '\n'; } Here, Array has a static member called array which contains 10 ints, starting at 0
  • How to initialize an array in C++ objects
    After reading How to initialize an array in C, in particular: Don't overlook the obvious solution, though: int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; I tried something like this: #include <iostream> class Something { private: int myArray[10]; public: Something() { myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; } int ShowThingy(int what) { return myArray[what]; } ~Something() {} }; int main () { Something Thing; std::cerr << Thing.ShowThingy(3); } And I get: ..\src\Something.cpp: In constructor 'Something::Something()': ..\src\Something.cpp:10:48: error: cannot convert '<brace
  • 如何在C ++对象中初始化数组(How to initialize an array in C++ objects)
    问题 在阅读了如何在C中初始化数组之后,尤其是: 但是,请不要忽略明显的解决方案: int myArray [10] = {5,5,5,5,5,5,5,5,5,5}; 我尝试过这样的事情: #include <iostream> class Something { private: int myArray[10]; public: Something() { myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; } int ShowThingy(int what) { return myArray[what]; } ~Something() {} }; int main () { Something Thing; std::cerr << Thing.ShowThingy(3); } 我得到: ..\src\Something.cpp: In constructor 'Something::Something()': ..\src\Something.cpp:10:48: error: cannot convert '<brace-enclosed initializer list>' to 'int' in assignment 在这种情况下,显而易见不是那么明显。 我真的希望阵列的启动也更加动态。 我累了: private: int *
  • constexpr和带有重新解释强制转换的静态const void指针的初始化,哪个编译器正确?(constexpr and initialization of a static const void pointer with reinterpret cast, which compiler is right?)
    问题 考虑以下代码: struct foo { static constexpr const void* ptr = reinterpret_cast<const void*>(0x1); }; auto main() -> int { return 0; } 上面的示例在g ++ v4.9(实时演示)中可以很好地编译,而在clang v3.4(实时演示)中不能编译并生成以下错误: 错误:constexpr变量“ ptr”必须由常量表达式初始化 问题: 根据标准,两个编译器中的哪一个是正确的? 声明这种表达的正确方法是什么? 回答1 TL; DR clang是正确的,这是已知的gcc错误。 您可以改用intptr_t并在需要使用该值时进行intptr_t ,或者如果该值不可行,则gcc和clang支持一些已记录在案的变通方法,该变通方法应允许您的特定用例。 细节 所以clang是在这一个正确的,如果我们去到C ++草案标准的11款5.19常量表达式第2款称: 条件表达式是核心常量表达式,除非它涉及以下之一作为可能评估的子表达式[...] 并包含以下项目符号: —一个reinterpret_cast(5.2.10); 一种简单的解决方案是使用intptr_t: static constexpr intptr_t ptr = 0x1; 然后在以后需要使用时进行投射:
  • 调用带有括号初始列表的显式构造函数:模棱两可?(Calling an explicit constructor with a braced-init list: ambiguous or not?)
    问题 考虑以下: struct A { A(int, int) { } }; struct B { B(A ) { } // (1) explicit B(int, int ) { } // (2) }; int main() { B paren({1, 2}); // (3) B brace{1, 2}; // (4) } (4)的brace结构清晰明确地称为(2) 。 在clang上, (3)的paren的构造明确地调用(1) ,其中与gcc 5.2一样,它无法编译为: main.cpp: In function 'int main()': main.cpp:11:19: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous B paren({1, 2}); ^ main.cpp:6:5: note: candidate: B::B(A) B(A ) { } ^ main.cpp:5:8: note: candidate: constexpr B::B(const B&) struct B { ^ main.cpp:5:8: note: candidate: constexpr B::B(B&&) 哪个编译器是正确的? 我怀疑clang在这里是正确的
  • 使用花括号初始化列表调用显式构造函数:模棱两可?(Calling an explicit constructor with a braced-init list: ambiguous or not?)
    问题 考虑以下: struct A { A(int, int) { } }; struct B { B(A ) { } // (1) explicit B(int, int ) { } // (2) }; int main() { B paren({1, 2}); // (3) B brace{1, 2}; // (4) } (4)中brace的构造明确无误地称为(2) 。 在 clang 上, (3)的paren构造明确调用(1) ,而在 gcc 5.2 上,它无法编译为: main.cpp: In function 'int main()': main.cpp:11:19: error: call of overloaded 'B(<brace-enclosed initializer list>)' is ambiguous B paren({1, 2}); ^ main.cpp:6:5: note: candidate: B::B(A) B(A ) { } ^ main.cpp:5:8: note: candidate: constexpr B::B(const B&) struct B { ^ main.cpp:5:8: note: candidate: constexpr B::B(B&&) 哪个编译器是对的? 我怀疑 clang 在这里是正确的,因为 gcc
  • Why can't I construct a queue/stack with brace-enclosed initializer lists? (C++11)
    Program 1: #include <iostream> #include <cstdlib> #include <vector> int main(){ //compiles successfully std::vector<int> vec{1,2,3,4,5}; return EXIT_SUCCESS; } Program 2: #include <iostream> #include <cstdlib> #include <queue> int main(){ //compiler error std::queue<int> que{1,2,3,4,5}; return EXIT_SUCCESS; } Error message: main.cpp: In function ‘int main()’: main.cpp:7:31: error: no matching function for call to ‘std::queue<int>::queue(<brace-enclosed initializer list>)’ main.cpp:7:31: note: candidates are: /usr/include/c++/4.6/bits/stl_queue.h:141:7: note: std::queue<_Tp, _Sequence>::queue(
  • g++ (4.7.2) 错误或功能,在编译时初始化静态数组时?(g++ (4.7.2) bug or feature, when initializing static arrays at compile-time?)
    问题 好的,所以我试图通过在编译时初始化一堆constexpr static int const数组来做一些聪明的事情。 尽管运行时性能根本不受初始化这些数组的控制,但这似乎是一个有趣的小练习。 我写了一个测试设置来看看它是否可能,我最终能够做到这一点: struct Test { constexpr static int const array[10] = Array<int, 10, 0, Increment>::array; }; constexpr int const Test::array[10]; int main() { cout << Test::array[3] << '\n'; } 这里, Array有一个名为array的静态成员,它包含 10 个int ,从 0 开始,其中每个后续元素的值由名为Increment的模板元编程函子确定(即{0, 1, ..., 9} ) . 正如预期的那样,程序打印出数字3 。 太棒了,对吧? 我现在可以编写仿函数并在编译时初始化数组将各种时髦的模式。 下一步:通过像这样使Test类模板取消对数组大小 10 的硬编码: template <size_t Size> struct Test { constexpr static int const array[Size] = Array<int, Size, 0
  • Do I need to put constexpr after else-if?
    Inspired by this answer, I tried to copy and paste (and add testing in main()) this code: template<typename T> std::tuple<int, double> foo(T a) { if constexpr (std::is_same_v<int, T>) return {a, 0.0}; else if (std::is_same_v<double, T>) return {0, a}; else return {0, 0.0}; } int main() { auto [x, y] = foo(""); std::cout << x << " " << y; } This is very straightforward - if T is deduced as int, we want to return a tuple of [a, 0.0]. If T is deduced as double, we want to return a tuple of [0, a]. Otherwise, we want to return [0, 0.0]. As you can see, in the main() function, I am calling foo with
  • gcc编译错误:强制类型转换指定数组类型(gcc compile error: cast specifies array type)
    问题 以下代码是完美有效的, int *ia = (int[]){1,3,5,7}; 但是当我编译下一行代码时, char *p = (char[]) "abc"; 海湾合作委员会说 test.c:87: error: cast specifies array type 似乎它们以相同的方式投射。 为什么第二个得到错误的味精? 就像你们说的那样,“ abc”是一个指针,不能将其转换为指针。 所以我的另一个问题是:为什么 char[] s = "abc"; 已验证。 上面的代码行在编译时如何工作? 回答1 这是有效的,因为右侧的表达式是C99复合文字,而不是强制转换: int *ia = (int[]){1,3,5,7}; /* Valid */ 但是,这是无效的,因为它是强制转换表达式,而不是复合文字。 正如GCC告诉您的那样,您不能转换为数组类型: char *p = (char[]) "abc"; /* NOT Valid */ 您可以通过将其设置为适当的复合文字来对其进行修复-用大括号表示: char *p = (char[]){"abc"}; /* Valid */ 回答2 C11 6.5.2.5p3: 由括号类型名称和括号括起来的初始化程序列表组成的后缀表达式是复合文字。 它提供了一个未命名的对象,其值由初始化程序列表提供。 (强调我的) 。 即,输入括号(char []
  • 模板化结构的大括号括起来的初始值设定项列表(Brace-enclosed initializer list of templated struct)
    问题 #include <array> #include <vector> #include <cinttypes> #include <iostream> using namespace std; template<size_t N> struct item_t { array<uint32_t, N> weight = {0}; }; int main(void) { vector<item_t<3>> items; items.emplace_back({{9,2,3}}); cout << items[0].weight[0] << endl; return 0; }; 我在这里有点茫然。 错误出现在 emplace_back 行上,不知道如何解决。 任何帮助或提示将不胜感激,谢谢。 编辑 gcc 版本 4.8.2 $ g++ -std=c++11 test.cpp test.cpp: In function ‘int main()’: test.cpp:16:30: error: no matching function for call to ‘std::vector<item_t<3ul> >::emplace_back(<brace-enclosed initializer list>)’ items.emplace_back({{9,2,3}}); ^ test
  • 无法从(could not convert from <brace-enclosed initializer list>)
    问题 它适用于struct RS : public JV<T,1>但不适用于struct RS : public JV<T,2> 。 error: could not convert ‘{(0, j), (0, j)}’ from ‘<brace-enclosed initializer list>’ to ‘WJ<float>’ 我必须重载operator,()吗? 代码: #include<iostream> struct B {}; template <std::size_t... Is> struct indices {}; template <std::size_t N, std::size_t... Is> struct build_indices : build_indices<N-1, N-1, Is...> {}; template <std::size_t... Is> struct build_indices<0, Is...> : indices<Is...> {}; template<class T,int N> struct JV { JV(B& j) : JV(j, build_indices<N>{}) {} template<std::size_t... Is> JV(B& j, indices<Is...>) : jit(j), F{{(void
  • 关于常量表达式的困惑(Confusion about constant expressions)
    问题 这是对该主题的某种跟进,并涉及其中的一小部分。 与上一个主题一样,让我们​​考虑我们的编译器具有用于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