简体   繁体   English

C ++:嵌套结构的平面初始化列表?

[英]C++: flat initializer list for nested struct?

Having defined 定义了

struct A {
  int a,b;
};

struct B {
  A a;
  int b;
};

the following initializations are obvious: 以下初始化很明显:

B b1 = { { 1 } };    // initializes b1.a.a
B b2 = { { 1, 2 } }; // initializes b1.a.a, b1.a.b
B b3 = { { 1 }, 2 }; // initializes b1.a.a, b1.b

But I am suprised that VC++ 2013 also allows these initializations without any warning: 但我很惊讶VC ++ 2013还允许这些初始化而没有任何警告:

B b4 = { 1 };       // initializes b4.a.a
B b5 = { 1, 2 };    // initializes b5.a.a, b5.a.b
B b6 = { 1, 2, 3 }; // initializes b6.a.a, b6.a.b, b6.b

Are flat initializer lists for nested structures/classes standard C++? 嵌套结构/类的标准初始化程序列表是标准C ++吗?

Yes, this is standard C++. 是的,这是标准的C ++。 In aggregate initialization (and only in aggregate initialization, not in other forms of list-initialization), braces can be elided, effectively flattening the containment hierarchy of an aggregate. 在聚合初始化中(并且在聚合初始化中,而不是在其他形式的列表初始化中),可以省略大括号,有效地展平聚合的包含层次结构。

Yes, it's a standard C++ which is described in the 8.5 Initializers . 是的,它是8.5初始化 程序中描述的标准C ++

It's called a brace elision and can be applied in the case of aggregate initialization. 它被称为大括号elision ,可以在聚合初始化的情况下应用。

From the n4296 , 8.5.1.12 Aggregates : n4296,8.5.1.12骨料

Braces can be elided in an initializer-list as follows. 可以在初始化列表中省略大括号,如下所示。 If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; 如果初始化列表以左括号开头,则后续的逗号分隔的initializer-clause列表初始化子集合的成员; it is erroneous for there to be more initializer-clauses than members. 如果有比成员更多的初始化子条款是错误的。 If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; 但是,如果子聚合的初始化列表不以左括号开头,则只从列表中获取足够的初始化子句来初始化子聚合的成员; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member. 剩下的任何初始化子句用于初始化当前子聚合为成员的聚合的下一个成员。

Here is another example from the 8.5.1.13 : 这是8.5.1.13的另一个例子:

struct A {
    int i;
    operator int();
};

struct B {
    A a1, a2;
    int z;
};

A a;
B b = { 4, a, a };

In this example a1 is initialized with 4 , a2 is initialized with a and z is initialized with the result of operator int() for a . 在该实施例A14-初始化,A2被初始化为az操作者INT()一个的结果初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM