class 聚合的元素

Elements of a class aggregate

我试图了解从 C++14 到 C++17 发生的关于聚合初始化的变化。来自 §9.4.2[dcl.init.aggr]/2:

The elements of an aggregate are:

  • (2.1) for an array, the array elements in increasing subscript order, or
  • (2.2) for a class, the direct base classes in declaration order, followed by the direct non-static data members ([class.mem]) that are not members of an anonymous union, in declaration order.

本段定义聚合 class 的元素是什么。特别是,我无法理解粗体句子的含义。我有这个例子来证明我的困惑:

struct Base { int mem1, mem2; }; 
struct Derived : Base { int mem3, mem4; };

Derived obj = { 1, 2, 3, 4 };

对象 obj 是一个集合,因为它满足 [dcl.init.aggr]/1 中定义的条件。然而,我的问题是这个聚合的元素是什么。好像元素是Base::mem1初始化为1,Base::mem2初始化为2,Derived::mem3初始化为3,Dervied::mem4初始化为4.

但是 [dcl.init.aggr]/2 的说法恰恰相反。据说元素是直接基数classes的数据成员,在本例中是Base,直接非静态数据后跟[=​​33=] Derived class 的成员。我是否正确解析了措辞?

我真的不知道我是否正确理解了这句话,但我想我没有。所以关于这一点的任何解释都会对我有很大帮助。

您对“聚合元素”概念的理解是正确的。然而,这并不是聚合初始化的结束。有brace elision:

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 elements of a subaggregate; it is erroneous for there to be more initializer-clauses than elements. 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 elements of the subaggregate; any remaining initializer-clauses are left to initialize the next element of the aggregate of which the current subaggregate is an element.

All implicit type conversions ([conv]) are considered when initializing the element with an assignment-expression. If the assignment-expression can initialize an element, the element is initialized. Otherwise, if the element is itself a subaggregate, brace elision is assumed and the assignment-expression is considered for the initialization of the first element of the subaggregate.

由于 Base b = 1; 不是有效的初始化语句,因此假定大括号省略,如第一段中所定义。