Considere el siguiente código:
struct A
{
// No data members
//...
};
template<typename T, size_t N>
struct B : A
{
T data[N];
}
Así es como debe inicializar B: B<int, 3> b = { {}, {1, 2, 3} };
quiero evitar el vacío {} innecesario para la clase base. Hay una solución propuesta por Jarod42 aquí , sin embargo, no funciona con elementos de inicialización por defecto: B<int, 3> b = {1, 2, 3};
está bien, pero B<int, 3> b = {1};
no lo es: b.data[1]
y b.data[2]
no son opción predeterminada inicializa a 0 y se produce un error de compilación. ¿Hay alguna forma (o habrá con c ++ 20) para "ocultar" la clase base de la construcción?
c++
initialization
c++20
aggregate-initialization
usuario7769147
fuente
fuente
template<class... Ts> B(Ts... args) : data{args...} {}
?Respuestas:
La solución más fácil es agregar un constructor variadic:
Si proporciona menos elementos en la
{...}
lista de inicializadores queN
, los elementos restantes en la matrizdata
se inicializarán como valor porT()
.fuente
B<Class, 5> b = {Class()};
Class
va a ser construido primero y luego se trasladó, mientras que mediante el uso de inicialización de agregadosClass
sería construida en el lugar, ningún movimiento involucradostd::tuple
argumentos y usarlos para construir objetos en el lugar. Pero la sintaxis será bastante engorrosa.Desde C ++ 20 puede usar inicializadores designados en la inicialización agregada .
fuente
Aún con el constructor, podrías hacer algo como:
Manifestación
SFINAE se hace principalmente para evitar crear un constructor de pseudo copia
B(B&)
.Necesitaría una etiqueta privada adicional para admitir
B<std::index_sequence<0, 1>, 42>
;-)fuente
((void)Is, T())...
? ¿Qué pasa si simplemente lo omites? ¿No se inicializarán los elementos restantesT()
de forma predeterminada?He encontrado otra solución que (no sé cómo) funciona a la perfección y resuelve el problema que discutíamos con la respuesta de Evg
fuente
this->data
ousing B_data::data;
acceder aldata
interiorB
.