Home > Article > Backend Development > Designated Initializers and Inheritance: Why Can\'t I Initialize an Employee with a Designated Initializer?
Designated Initializers in C 20: An Enigma with Employee Initialization
C 20's designated initializers allow precise member initialization for classes considered aggregates. However, the question arises when a class inherits from an aggregate base class, as exemplified by the code provided:
<code class="cpp">#include <iostream> constexpr unsigned DEFAULT_SALARY {10000}; struct Person { std::string name{}; std::string surname{}; unsigned age{}; }; struct Employee : Person { unsigned salary{DEFAULT_SALARY}; }; int main() { std::cout << std::boolalpha << std::is_aggregate_v<Person> << '\n'; // true is printed std::cout << std::boolalpha << std::is_aggregate_v<Employee> << '\n'; // true is printed Person p{.name{"John"}, .surname{"Wick"}, .age{40}}; // it's ok Employee e1{.name{"John"}, .surname{"Wick"}, .age{40}, .salary{50000}}; // doesn't compile, WHY ? // For e2 compiler prints a warning "missing initializer for member 'Employee::<anonymous>' [-Wmissing-field-initializers]" Employee e2 {.salary{55000}}; }</code>
In this case, both Person and Employee are considered aggregates, yet Employee cannot be initialized with designated initializers. The explanation lies in the C 20 Standard's regulation regarding designated initializers:
According to the C 20 Standard (9.3.1 Aggregates. p. #3), "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."
This means that designated initializers can only initialize data members directly declared in the class, not members inherited from a base class.
Therefore, initializing Employee using designated initializers as e1 is incorrect. Instead, the usual list initialization must be used:
<code class="cpp">Employee e1{ "John", "Wick", 40, 50000 };</code>
Alternatively, since Employee directly inherits from Person, one can use a nested designated initializer for the base class:
<code class="cpp">Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };</code>
This approach correctly initializes the Person base class with designated initializers while employing a regular initializer for the Employee class.
The above is the detailed content of Designated Initializers and Inheritance: Why Can\'t I Initialize an Employee with a Designated Initializer?. For more information, please follow other related articles on the PHP Chinese website!