84

代码:

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

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

4

2 回答 2

71

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 缺陷 #1270。如果提议的解决方案被采纳,其他形式的列表初始化将允许大括号省略,以下将是格式良好的:

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

(感谢 Ville Voutilainen 查找缺陷报告。)

于 2012-07-09T17:32:18.557 回答
31

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

于 2012-07-09T17:33:09.883 回答