这个std::array的内联初始化有什么问题?

13

考虑以下声明:

#include <array>

struct X
{
    //std::array<bool,3> arr={false,false,false};
    bool brr[3]={false,false,false};
};

代码原本可以被g++ 5.2正常编译,但如果我取消注释std::array的话,则会出现错误:

test.cpp:5:46: error: array must be initialized with a brace-enclosed initializer
     std::array<bool,3> arr={false,false,false};
                                              ^
test.cpp:5:46: error: too many initializers for ‘std::array<bool, 3u>’

然而,在 main() 函数中,这个声明可以无问题地工作。此外,以下初始化也可以在 struct X 中工作:

std::array<bool,3> arr={{false,false,false}};

为什么在结构定义中不能使用单括号进行简单初始化?


1
注意,在C++11中,与C++14不同的是,在类中初始化器会使结构体变成非聚合体。 - Shafik Yaghmour
1个回答

24

这看起来像是gcc的一个bug,请参考:Bug 65815 - brace elision doesn't work in NSDMI。报告中说:

On Page 975 of "The C++ Programming Language", 4th edition, Bjarne Stroustrup says:

"An array can be initialized by an initializer list: array a1 = { 1, 2, 3 };"

and Clang (V 3.5) accepts it. However, G++ 4.9.2 thinks this is an error:

"error: array must be initialized with a brace-enclosed initializer
   const std::array<double, 3> _ar0val = {1.0, -1.0, 1.0};"
问题被缩小到以下测试用例:
struct array {
  int data [2];
};

struct X {
  array a = { 1, 2 };
};

看起来修复已经在主版本中完成了,原帖中的代码在该版本中可以正常运行,请查看演示

如错误报告中所述,使用内部花括号是一种可能的解决方法:

std::array<bool,3> arr={ {false,false,false} };
                         ^                 ^

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接