J'ai une question sur l'une des fonctionnalités c ++ 20, les initialiseurs désignés (plus d'informations sur cette fonctionnalité ici )
#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}};
}
Ce code a été compilé avec gcc 9.2.0 et -Wall -Wextra -std=gnu++2a
flags.
Comme vous pouvez le voir ci-dessus, les deux structures Person
et Employee
sont des agrégats, mais l'initialisation d' Employee
agrégat n'est pas possible à l'aide des initialiseurs désignés.
Quelqu'un pourrait-il m'expliquer pourquoi?
c++
aggregate
c++20
designated-initializer
MateuszGierczak
la source
la source
struct Employee : public Person
public
ou àprivate
chaque fois ... merci quand mêmestruct
s hérite publiquement par défautRéponses:
Selon la norme C ++ 20 (9.3.1 Agrégats. P. # 3)
Vous ne pouvez donc pas utiliser la liste d'initialisation désignée pour initialiser les membres de données des classes de base.
Utilisez plutôt l'initialisation de liste habituelle comme
ou
ou comme @ Jarod42 l'a souligné dans un commentaire, vous pouvez écrire
Dans ce cas, la classe de base directe est initialisée par une liste d'initialisation désignée tandis que la classe Employe dans son ensemble est initialisée par une liste d'initialisation non désignée.
la source
Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };
.Vous pouvez avoir plusieurs champs avec le même nom de différentes bases,
donc logiquement, vous devez fournir le nom de la base recherchée, mais il semble qu'il n'y ait aucun moyen de le faire.
De plus, l'initialisation désignée par C ++ est plus contrainte que C:
la source