聚合初始化中的大括号在很大程度上是可选的,因此您可以编写:
S c_arr[] = {1, 2, 3, 4}; // OK
std::array<S, 2> std_arr = {1, 2, 3, 4}; // OK
但是,如果您确实添加了大括号,则会将大括号应用于下一个子对象。不幸的是,当您开始嵌套时,这会导致愚蠢的代码有效,而像您这样的合理代码则无效。
std::array<S, 2> std_arr = {{1, 2, 3, 4}}; // OK
std::array<S, 2> std_arr = {1, 2, {3, 4}}; // OK
std::array<S, 2> std_arr = {1, {2}, {3, 4}}; // OK
这些都没问题。{1, 2, 3, 4}
是 的S[2]
成员的有效初始化程序std_arr
。{2}
没关系,因为它试图初始化一个int
,并且{2}
是一个有效的初始化器。{3, 4}
被视为 的初始化器S
,它也适用于此。
std::array<S, 2> std_arr = {{1, 2}, {3, 4}}; // error
这是不行的,因为{1, 2}
它被视为S[2]
成员的有效初始化程序。剩余的int
子对象初始化为零。
然后你有{3, 4}
,但没有更多的成员要初始化。
正如评论中指出的那样,
std::array<S, 2> std_arr = {{{1, 2}, {3, 4}}};
也有效。嵌套{{1, 2}, {3, 4}}
是S[2]
成员的初始化器。这{1, 2}
是第一个S
元素的初始化器。这{3, 4}
是第二个S
元素的初始化器。
我在这里假设它std::array<S, 2>
包含一个 type 的数组成员S[2]
,它在当前的实现中执行,并且我相信它可能会得到保证,但是之前已经在 SO 中介绍过,目前还不能保证。