std::array初始化代码编译出现too many initializers错误的原因?

std::array初始化代码编译出现too many initializers错误的原因?

在C++11引入initializer_list后,由于C++11标准(§8.5.1/11)中规定

所以当出现

的时候,有这么几种情况:

这种情况下,程序会把大括号里的值按类内成员变量的定义顺序依次赋值,如果参数过多,会报错“too many initializers”

这时候,这句话等价于

也就是说,程序会调用T里和a相匹配的构造函数来构造x

这时候,根据一开始提到的标准里的规定,事实上,这句话等价于

和2一样,程序会调用T里以initializer_list为参数的那个构造函数来构造x,其中initializer_list里的参数为a

T里既有一个以initializer_list为参数的构造函数,也有另外的用户自定义的构造函数,这时候,程序优先按3来构造,典型的例子就是vector

这样的初始化是让a里一开始就有2个元素1、2,而不是只有1个为2的元素

===

这是4种比较基本的情况,但事实上,还有可能有更多的奇怪的东西,就比如现在提出的这个问题

在说这个问题之前,首先要指出的是,array和其他容器并不一样,它是一个聚合类,也就是说,它没有用户自定义的构造函数,所以分析的时候得按1来处理,你可以把它看成

然后回到问题来,一个一个看

===

根据1,它会把{"a"}, {"b"}按定义顺序依次给array里的成员变量赋值,它在把{"a"}赋值给__array后(__array[2] = {"a"};),对于{"b"},它找不到可以赋值的成员,所以会报错

不过你有可能会问,既然它是聚合类,那为什么还可以直接像下面这样子呢?

还是根据一开始提到的标准里的规定,所以大括号省略掉了,具体例子可以看给出的参考的第一个链接,其实就和C语言里定义二维数组一样,你可以写成

也可以不写里面的大括号,直接写

而题主说

事实上其他类型也是不行的,只是你写的和这个不一样所以没报错,你要是写成和这个一样的形式:

也是会报错的

===

在我电脑上没有出现报错,按理来说应该也不会报错,题主可以提供一下更详细的信息

===

这个我也没有查到具体的原因,但经测试发现,只有基本类型会报错,而且既然VS2015不会报错,而gcc报错,那这有可能是个UB

参考:

When can outer braces be omitted in an initializer list?

Why is the C++ initializer_list behavior for std::vector and std::array different?

Ignoring GCC "error: braces around scalar initializer for type" errors. Make them warnings