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

时间:2012-07-09 17:30:24

标签: c++ stl c++11

代码:

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

为什么我需要std :: array的双花括号?

2 个答案:

答案 0 :(得分:59)

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

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

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

使用这种旧式聚合初始化,可以省略额外的括号,因此这相当于:

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

然而,这些额外的括号可能只能在“T x = { a };形式的声明中被省略”(C ++11§8.5.1/ 11),也就是旧格式=时用来 。允许括号省略的此规则不适用于直接列表初始化。这里的脚注如下:“在列表初始化的其他用途中不能省略大括号。”

有关此限制的缺陷报告:CWG defect #1270。如果采用提议的解决方案,则允许使用大括号来进行其他形式的列表初始化,并且以下内容将是格式良好的:

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

(向Ville Voutilainen提示找到缺陷报告。)

答案 1 :(得分:24)

因为std::vector提供了一个接受std::initializer_list<T>的构造函数,而std::array没有构造函数,并且{1, 2, 3, 4}支撑的init-list实际上不会被解释为{ {1}},但std::initializer_list的内部C样式数组的聚合初始化(第二组括号来自的地方:一个用于std::array,一个用于内部C样式的成员数组)