Ich habe eine Frage zu einer der C ++ 20-Funktionen, die als Initialisierer bezeichnet werden (weitere Informationen zu dieser Funktion hier ).
#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}};
}
Dieser Code wurde mit gcc 9.2.0 und -Wall -Wextra -std=gnu++2a
Flags kompiliert .
Wie Sie oben sehen können, sind beide Strukturen Person
und Employee
Aggregate, aber die Initialisierung des Employee
Aggregats ist mit bestimmten Initialisierern nicht möglich.
Könnte mir jemand erklären warum?
c++
aggregate
c++20
designated-initializer
MateuszGierczak
quelle
quelle
struct Employee : public Person
public
oderprivate
jedes Mal ... trotzdem dankestruct
s erben standardmäßig öffentlichAntworten:
Gemäß dem C ++ 20-Standard (9.3.1 Aggregate. S. # 3)
Daher dürfen Sie die angegebene Initialisierungsliste nicht zum Initialisieren von Datenelementen von Basisklassen verwenden.
Verwenden Sie stattdessen die übliche Listeninitialisierung wie
oder
oder wie @ Jarod42 in einem Kommentar zeigte, den Sie schreiben können
In diesem Fall wird die direkte Basisklasse durch eine festgelegte Initialisierungsliste initialisiert, während die Klasse Employe insgesamt durch eine nicht festgelegte Initialisierungsliste initialisiert wird.
quelle
Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };
.Möglicherweise haben Sie mehrere Felder mit demselben Namen aus verschiedenen Basen.
Logischerweise sollten Sie den Namen der gewünschten Basis angeben, aber es scheint, dass es keine Möglichkeit gibt, dies zu tun.
Darüber hinaus ist die von C ++ festgelegte Initialisierung stärker eingeschränkt als C:
quelle