c++ aggregate c++20 designated-initializer

Inicializadores designados en C++ 20



aggregate c++20 (2)

De acuerdo con el estándar C ++ 20 (9.3.1 Agregados. P. # 3)

(3.1) - Si la lista de inicializadores es una lista de inicializadores designada, el agregado será de tipo de clase, el identificador en cada designador nombrará un miembro de datos no estático directo de la clase y los elementos inicializados explícitamente del agregado son los elementos que son, o contienen, esos miembros.

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

Employee e1{ "John", "Wick", 40, 50000 };

o

Employee e1{ { "John", "Wick", 40 }, 50000 };

o como @ Jarod42 señaló en un comentario que puedes escribir

Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };

En este caso, la clase base directa se inicializa mediante una lista de inicializadores designada, mientras que la clase Empleado en su conjunto se inicializa mediante una lista de inicializadores no designados.

Tengo una pregunta sobre una de las características de c ++ 20, inicializadores designados (más información sobre esta característica here )

#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 agregado Employee no es posible utilizando inicializadores designados.

¿Podría alguien explicarme por qué?


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.

// Invalid too: Employee e1{.Person.name{"John"}, .Person.surname{"Wick"}, .Person.age{40}, .salary{50000}}; Employee e2{.Person{.name{"John"}, .surname{"Wick"}, .age{40}}, .salary{50000}};

Además, la inicialización designada por C ++ está más restringida que C:

Nota: la inicialización designada fuera de orden, la inicialización designada anidada, la mezcla de inicializadores designados e inicializadores regulares y la inicialización designada de matrices son compatibles con el lenguaje de programación C, pero no están permitidos en C ++.