Elements of a class aggregate

75 views Asked by At

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?.

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.

1

There are 1 answers

0
Nicol Bolas On BEST ANSWER

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.