Considere o seguinte código:
struct A
{
// No data members
//...
};
template<typename T, size_t N>
struct B : A
{
T data[N];
}
É assim que você precisa inicializar B: B<int, 3> b = { {}, {1, 2, 3} };
quero evitar o vazio desnecessário {} para a classe base. Há uma solução proposta por Jarod42 aqui , no entanto, ela não funciona com a inicialização padrão dos elementos: B<int, 3> b = {1, 2, 3};
está bem, mas B<int, 3> b = {1};
não está: b.data[1]
e b.data[2]
não é inicializada com o padrão como 0, e ocorre um erro do compilador. Existe alguma maneira (ou haverá com c ++ 20) de "ocultar" a classe base da construção?
c++
initialization
c++20
aggregate-initialization
user7769147
fonte
fonte
template<class... Ts> B(Ts... args) : data{args...} {}
?Respostas:
A solução mais fácil é adicionar um construtor variável:
Se você fornecer menos elementos na
{...}
lista do inicializador do queN
, os elementos restantes na matrizdata
serão inicializados por valor como antesT()
.fonte
B<Class, 5> b = {Class()};
Class
que será construído primeiro e depois movido, enquanto o uso de inicialização agregadaClass
fosse construído, não haverá movimentação envolvidastd::tuple
em argumentos e usá-los para construir objetos no local. Mas a sintaxe será bastante complicada.Desde o C ++ 20, você pode usar inicializadores designados na inicialização agregada .
fonte
Ainda com o construtor, você pode fazer algo como:
Demo
O SFINAE é feito principalmente para evitar a criação de pseudo-construtor de cópias
B(B&)
.Você precisaria de uma tag privada extra para apoiar
B<std::index_sequence<0, 1>, 42>
;-)fonte
((void)Is, T())...
? E se você simplesmente omiti-lo? Os elementos restantes não serão inicializadosT()
por valor por padrão?Encontrei outra solução que (não sei como) funciona perfeitamente e resolve o problema que estávamos discutindo sob a resposta de Evg
fonte
this->data
ouusing B_data::data;
acessar pordata
dentroB
.