Home > Enterprise >  Elements of a class aggregate
Elements of a class aggregate

Time:04-20

I am trying to understand the changes that happened from C 14 to C 17 regarding aggregate initialization. From §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.

This paragraph defines what the elements of an aggregate class are. In particular, I can't get what the bold sentence means. I have this example to demonstrate my confusion:

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

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

The object obj is an aggregate since it satisfies the criteria defined in [dcl.init.aggr]/1. My problem, however, is what are the elements of this aggregate. It seems that the elements are Base::mem1 initialized with 1, Base::mem2 initialized with 2, Derived::mem3 initialized with 3, and Dervied::mem4 initialized with 4.

But [dcl.init.aggr]/2 states the opposite. It is said that the elements are the data members of the direct base classes, which is Base in this case, followed by the direct non-static data members of the Derived class (Am I parsed the wording correctly?).

The effect of the word "followed by" makes me confused; So I thought it means that the data members of Derived are the first elements of the aggregate obj, hence they're initialized first, then the data members of Base are the rest elements of the aggregate, hence they are initialized next. Therefore, Derived::mem3 will be 1 and Derived::mem4 will be 2, then Base::mem1 will be 3 and Base::mem2 will be 4.

I really don't know whether or not I understood the quote correctly, but I think I don't. So any explanation regarding this point will help me alot.

CodePudding user response:

Your understanding of the concept "elements of an aggregate" is correct. However, that's not the end of aggregate initialization. There is 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.

Since Base b = 1; is not a valid initialization statement, brace elision is assumed, as defined in the first paragraph.

  • Related