In C++20 (latest draft), given the following code:
struct B { int mb; };
struct D : B { int md; };
which of these six expressions are ill-formed and which are not?
/*1*/ D{42, 43}
/*2*/ D{{42}, 43}
/*3*/ D{42, .md = 43}
/*4*/ D{{42}, .md = 43}
/*5*/ D{.mb = 42, .md = 43}
/*6*/ D{{.mb = 42}, .md = 43}
(2) is your standard, explicit aggregate initialization. It's fine.
(1) is aggregate initialization with brace elision around the B
subobject. This is also fine.
(3) and (4) are mixing designated initializers with non-designated initializers, which is not allowed. The grammar for designated-initializer-list only allows a designated-initializer-clause, which is a designator (.
identifier) followed by a brace-or-equal-nitializer. There is no other form.
(5) and (6) are trying to designated-initialize a base class subobject, which is also not allowed. All the designators have to name direct non-static data members. [dcl.init.aggr]/3.1 says:
If the initializer list is a designated-initializer-list, the aggregate shall be of class type, the identifier in each designator shall name a direct non-static data member of the class, [...]
The proposal makes it clear that both of these are intended. It comments that:
The base class objects will be initialized with {}. We do not have a concrete use case for someindepth control of how to initialize the base class objects, and the proposed design is forwardcompatible, therefore we suggest to address this issue in another proposal.
and:
Either all designators, or none.
with a future issue:
Do we allow a designation list to appear in a list-initializer as a suffix, e.g.
A { 1, 2, .c= 3, .d = 4 }
?