Mik*_*ail 7 c++ arrays initialization aggregate-initialization c++14
我想知道,为什么std_arr在下面的代码中声明会产生错误,同时c_arr编译得很好:
struct S { int a, b; };
S c_arr[] = {{1, 2}, {3, 4}}; // OK
std::array<S, 2> std_arr = {{1, 2}, {3, 4}}; // Error: too many initializers
Run Code Online (Sandbox Code Playgroud)
双方std::array并S都聚集.从cppreference.com上的聚合初始化:
如果initializer子句是嵌套的braced-init-list(它不是表达式且没有类型),则相应的类成员本身就是一个聚合:聚合初始化是递归的.
为什么这个初始化std::array不能编译?
小智 8
聚合初始化中的大括号在很大程度上是可选的,因此您可以编写:
S c_arr[] = {1, 2, 3, 4}; // OK
std::array<S, 2> std_arr = {1, 2, 3, 4}; // OK
Run Code Online (Sandbox Code Playgroud)
但是,如果添加大括号,则会使用大括号将其应用于下一个子对象.不幸的是,当你开始嵌套时,这会导致愚蠢的代码有效,而像你这样的敏感代码无效.
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
Run Code Online (Sandbox Code Playgroud)
这些都没关系.{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
Run Code Online (Sandbox Code Playgroud)
这不合适,因为{1, 2}它被视为S[2]成员的有效初始化者.剩余的int子对象初始化为零.
然后你有{3, 4},但没有更多成员初始化.
正如评论中指出的那样,
std::array<S, 2> std_arr = {{{1, 2}, {3, 4}}};
Run Code Online (Sandbox Code Playgroud)
也有效.嵌套{{1, 2}, {3, 4}}是S[2]成员的初始化者.这{1, 2}是第一个S元素的初始化者.这{3, 4}是第二个S元素的初始化.
我假设这里std::array<S, 2>包含一个类型的数组成员S[2],它在当前的实现上执行,并且我相信它可能会得到保证,但之前已经涵盖了SO,目前还没有保证.
| 归档时间: |
|
| 查看次数: |
1146 次 |
| 最近记录: |