c++ - Inicializando una estructura con inicialización agregada e inicializadores de miembros
c++11 constructor (2)
Bjarne Stroustrup y Richard Smith plantearon un problema sobre la inicialización agregada y los inicializadores de miembros que no funcionan juntos.
La definición de agregado se modifica ligeramente en el estándar C ++ 11 y C ++ 14.
Del borrador estándar de C ++ 11 n3337 sección 8.5.1 dice que:
Un agregado es una matriz o una clase (Cláusula 9) sin constructores proporcionados por el usuario (12.1), sin inicializadores con refuerzo o igual para miembros de datos no estáticos (9.2), no hay miembros de datos no estáticos privados o protegidos ( Cláusula 11), sin clases base (Cláusula 10) y sin funciones virtuales (10.3).
Pero la sección 8.5.1 del borrador n3797 de la norma C ++ 14 dice que:
Un agregado es una matriz o una clase (Cláusula 9) sin constructores proporcionados por el usuario (12.1), sin miembros de datos no estáticos protegidos o privados (Cláusula 11), sin clases base (Cláusula 10) y sin funciones virtuales (10.3) ).
Por lo tanto, cuando usa el inicializador de miembro de clase ( es decir, el inicializador igual ) para el id
miembro de datos en C ++ 11, ya no permanece agregado y no puede escribir ABC abc{"hi", 0};
Para inicializar una struct ABC.
Porque ya no queda tipo agregado después de eso. Pero tu código es válido en C ++ 14. (Ver demostración en vivo here ).
Esta pregunta ya tiene una respuesta aquí:
Considere el siguiente ejemplo:
#include <iostream>
#include <string>
struct ABC
{
std::string str;
unsigned int id ;/* = 0 : error: no matching constructor for initialization of ''ABC''*/
};
int main()
{
ABC abc{"hi", 0};
std::cout << abc.str << " " << abc.id << std::endl;
return 0;
}
Al definir la estructura ABC sin valor predeterminado para id clang 3.xy gcc 4.8.x compile el código sin problemas. Sin embargo, después de agregar un argumento predeterminado para "id", aparece el mensaje de error:
13 : error: no matching constructor for initialization of ''ABC''
ABC abc{"hi", 0};
^ ~~~~~~~~~
4 : note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 2 were provided
struct ABC
^
4 : note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 2 were provided
4 : note: candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 2 were provided
1 error generated.
Compilation failed
Desde un punto de vista técnico, ¿qué sucede cuando defino id con un argumento predeterminado y por qué no es posible la inicialización agregada en ese caso? ¿Defino implícitamente algún tipo de constructor?
En c ++, la estructura y las clases son las mismas, excepto que las estructuras tienen miembros públicos predeterminados y las clases son privadas. Si quieres usar valores iniciales, creo que tienes que escribir un constructor o usar algo como esto:
struct ABC
{
std::string str;
unsigned int id;
} ABC_default = {"init", 0 }; //initial values
int main()
{
ABC abc = ABC_default;
std::cout << abc.str << " " << abc.id << std::endl;
return 0;
}