Tengo una pregunta sobre una de las características de c ++ 20, inicializadores designados (más información sobre esta característica aquí )
#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}};
}
Este código fue compilado con gcc 9.2.0 y -Wall -Wextra -std=gnu++2a
flags.
Como puede ver arriba, ambas estructuras Person
y Employee
son agregados, pero la inicialización del Employee
agregado no es posible utilizando inicializadores designados.
¿Podría alguien explicarme por qué?
c++
aggregate
c++20
designated-initializer
MateuszGierczak
fuente
fuente
struct Employee : public Person
public
oprivate
cada vez ... gracias de todos modosstruct
s hereda públicamente por defectoRespuestas:
De acuerdo con el estándar C ++ 20 (9.3.1 Agregados. P. # 3)
Por lo tanto, no puede usar la lista de inicializadores designada para inicializar miembros de datos de clases base.
Utilice en su lugar la inicialización de lista habitual como
o
o como @ Jarod42 señaló en un comentario que puedes escribir
En este caso, la clase base directa se inicializa mediante una lista de inicializadores designada, mientras que la clase Empleado en su totalidad se inicializa mediante una lista de inicializadores no designados.
fuente
Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };
.Es posible que tenga varios campos con el mismo nombre desde diferentes bases,
lógicamente, debe proporcionar el nombre de la base deseada, pero parece que no hay forma de hacerlo.
Además, la inicialización designada por C ++ está más restringida que C:
fuente