为什么std :: vector和std :: array的C ++ initializer_list行为不同?

码:

std::vector<int> x{1,2,3,4}; std::array<int, 4> y{{1,2,3,4}}; 

为什么我需要双花括号为std ::数组?

std::array<T, N>是一个集合:它没有任何用户声明的构造函数,甚至没有一个采用std::initializer_list 。 使用大括号进行初始化是使用聚合初始化进行的 ,这是从Cinheritance的C ++特性。

聚合初始化的“旧式”使用=

 std::array<int, 4> y = { { 1, 2, 3, 4 } }; 

使用这种旧的聚合初始化方式,可以省去额外的大括号,所以这相当于:

 std::array<int, 4> y = { 1, 2, 3, 4 }; 

但是,这些额外的大括号只能在“ T x = { a }; ”forms的声明中被忽略掉(C ++ 11§8.5.1/ 11),也就是说,当使用旧的style = 。 允许大括号的规则不适用于直接列表初始化。 这里的脚注如下:“在其他使用列表初始化的过程中不能忽略大括号”。

有关于此限制的缺陷报告: CWG缺陷#1270 。 如果采纳提议的决议,则允许使用大括号作为其他forms的列表初始化,以下内容将是完整的:

 std::array<int, 4> y{ 1, 2, 3, 4 }; 

(为了find缺陷报告,请向Ville Voutilainen提供信息。)

因为std::vector提供了一个构造函数来接受std::initializer_list<T> ,而std::array没有构造函数,而{1, 2, 3, 4}加载的init-list实际上并不被解释为std::initializer_list ,但聚合初始化的内部C风格的数组std::array (这是第二套大括号来自:一个为std::array ,一个为内部的C样式成员数组)。