Home  >  Article  >  Backend Development  >  Designated Initializers and Inheritance: Why Can\'t I Initialize an Employee with a Designated Initializer?

Designated Initializers and Inheritance: Why Can\'t I Initialize an Employee with a Designated Initializer?

DDD
DDDOriginal
2024-11-02 08:06:02105browse

  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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn