Tenho uma pergunta sobre um dos recursos do c ++ 20, inicializadores designados (mais informações sobre esse recurso aqui )
#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 foi compilado com o gcc 9.2.0 e -Wall -Wextra -std=gnu++2a
sinalizadores.
Como você pode ver acima, ambas as estruturas Person
e Employee
são agregados, mas a inicialização do Employee
agregado não é possível usando inicializadores designados.
Alguém poderia me explicar o porquê?
c++
aggregate
c++20
designated-initializer
MateuszGierczak
fonte
fonte
struct Employee : public Person
public
ouprivate
toda vez ... obrigado mesmo assimstruct
s herdam publicamente por padrãoRespostas:
De acordo com o padrão C ++ 20 (9.3.1 Agregados. P. # 3)
Portanto, você não pode usar a lista inicializada designada para inicializar membros de dados das classes base.
Use a inicialização usual da lista, como
ou
ou como @ Jarod42 apontou em um comentário que você pode escrever
Nesse caso, a classe base direta é inicializada por uma lista de inicializadores designada, enquanto a classe Employe no total é inicializada por uma lista de inicializadores não designados.
fonte
Employee e1{ { .name{"John"}, .surname{"Wick"}, .age{40} }, 50000 };
.Você pode ter vários campos com o mesmo nome de diferentes bases,
portanto, logicamente, você deve fornecer o nome da base desejada, mas parece que não há como fazê-lo.
Além disso, a inicialização designada por C ++ é mais restrita que C:
fonte