Designated Initializers in C 20: Understanding Restrictions
In C 20, designated initializers provide a convenient way to initialize specific members of an aggregate. However, these initializers have certain limitations.
Consider the example code provided:
<code class="cpp">struct Person { std::string name{}; std::string surname{}; unsigned age{}; }; struct Employee : Person { unsigned salary{DEFAULT_SALARY}; }; int main() { Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // Possible Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // Error Employee e2{.salary{55000}}; // Warning }</code>
As indicated in the code, both Person and Employee are aggregates. However, the initialization of the Employee aggregate using designated initializers (e1) fails to compile. Why is this?
The answer lies in the C 20 standard, specifically in section 9.3.1 Aggregates, point 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."
In other words, designated initializers can only be used to initialize members of the current class. They cannot be used for inherited members or base class members. This restriction is why the initialization of e1 is invalid.
To initialize e1 correctly, one can use the usual list initialization syntax:
<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 }; // Works</code>
Alternatively, one can use a combination of designated and non-designated initializers to achieve the same result:
<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 }; // Also works</code>
In this case, the direct base class (Person) is initialized using a designated initializer list, while the entire Employee class is initialized using a non-designated initializer list.
Overall, it's important to remember the limitations of designated initializers when working with class hierarchies in C 20. By using the appropriate initialization syntax, one can effectively and accurately initialize data members of both base and derived classes.
The above is the detailed content of Why can't I use designated initializers to initialize inherited members in C 20?. For more information, please follow other related articles on the PHP Chinese website!