Designated initializers in C++20

According to the C++ 20 Standard (9.3.1 Aggregates. p. #3)

(3.1) — 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, and the explicitly initialized elements of the aggregate are the elements that are, or contain, those members.

So you may not use the designated initializer list to initialize data members of base classes.

Use instead the usual list initialization like

Employee e1{ "John", "Wick", 40, 50000 };

or

Employee e1{ { "John", "Wick", 40 }, 50000 };

or as @Jarod42 pointed in a comment you can write

Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };

In this case the direct base class is initialized by a designated initializer list while the class Employe in whole is initialised by a non-designated initializer list.


You might have several fields with same name from different bases,

so logically, you should provide name of the wanted base, but it seems there is no way to do it.

// Invalid too:
Employee e1{.Person.name{"John"}, .Person.surname{"Wick"}, .Person.age{40}, .salary{50000}};
Employee e2{.Person{.name{"John"}, .surname{"Wick"}, .age{40}}, .salary{50000}};

In addition C++ designated initialization is more constrained than C:

Note: out-of-order designated initialization, nested designated initialization, mixing of designated initializers and regular initializers, and designated initialization of arrays are all supported in the C programming language, but are not allowed in C++.