0 es una constante
S.4.9 puntero nulo:
Una constante puntero nulo es una expresión de la constante integral (5.19) rvalue de tipo entero que se evalúa como cero.
Una constante puntero nulo se puede convertir en cualquier otro tipo de puntero:
S.4.9:
Una constante puntero nulo se puede convertir en un tipo de puntero; el resultado es el valor de puntero nulo de ese tipo
Lo que diste para la definición de A
se considera un agregado:
S.8.5.1:
Un agregado es una matriz o una clase sin constructores declarados por el usuario, no hay miembros de datos no estáticos privados o protegidos, no hay clases base y no hay funciones virtuales.
especifica una cláusula de inicialización:
S.8.5.1:
Cuando un agregado se inicializa el inicializador puede contener una cláusula inicializador que consiste en una abrazadera cerrada, lista separada por comas de inicializador-cláusulas para los miembros del agregado
A
contiene un miembro del agregado de tipo std::string
, y la cláusula de inicialización se aplica a él.
Su agregado es copia-inicializado
Cuando un agregado (si clase o matriz) contiene los miembros de tipo de clase y se inicializa por un inicializador-lista abrazadera cerrada, cada uno de tales miembros es copia -inicializado
ejemplar significa que usted tiene el equivalente a std::string s = 0
o std::string s = 42
inicialización;
S.8.5-12
La inicialización que se produce en el paso de argumentos, retorno de la función, lanzar una excepción (15.1), la manipulación una excepción (15.3), y las listas de inicializador abrazadera-cerrado (8,5 .1) se llama inicialización de copia y es equivalente a con la forma T x = a;
std::string s = 42
no se compilará porque no hay conversión implícita, std::string s = 0
compilará (porque existe una conversión implícita), pero los resultados en el comportamiento no definido. constructor de
std::string
's para const char*
no se define como explicit
que significa que puede hacer esto: std::string s = 0
Sólo para mostrar que las cosas son realmente estar copia-inicializado, se podría hacer esta sencilla prueba:
class mystring
{
public:
explicit mystring(const char* p){}
};
struct A {
mystring s;
};
int main()
{
//Won't compile because no implicit conversion exists from const char*
//But simply take off explicit above and everything compiles fine.
A a = {0};
return 0;
}
La plantilla de clase 'boost :: array' es un agregado también. Entonces puede hacer 'array a = {" foo "," bar "};' con él, por ejemplo. Además, mi lazy-construct-array es un agregado también: http://stackoverflow.com/questions/2662417/c-suppress-automatic-initialization-and-destruction/2662526#2662526 –
Conversiones implícitas + agregados ... ಠ_ಠ –
@litb cuando vi por primera vez esa función de 'boost :: array' tuve una iluminación, también conocida como satisfacción sexual del cerebro. Las cosas simples que tienen tanto sentido tienden a hacerme eso. – wilhelmtell