Valor de C++14-inicialización con constructor eliminado
Tengo un malentendido:
Vamos a marcar el constructor predeterminado de la estructura A como eliminado:
struct A
{
A() = delete;
};
La siguiente instrucción está bien formada y ¿cuál es ese efecto?:
A a{};
Desde cppreference inicialización de valores:
1) Si T es un tipo de clase sin constructor predeterminado o con un constructor predeterminado proporcionado por el usuario o con un predeterminado eliminado constructor, el objeto está inicializado por defecto.
Pero entonces el efecto de la inicialización predeterminada es:
Si T es un tipo de clase, se llama al constructor predeterminado para proporcionar valor inicial para el nuevo objeto.
O es la inicialización agregada? ¡Gracias!
2 answers
Su struct A
es :
- un tipo de clase que tiene:
- no hay constructores proporcionados por el usuario1,
- no hay miembros de datos no estáticos privados o protegidos,
- sin clases base,
- no hay funciones miembro virtuales.
Por lo tanto, se califica como un tipo agregado , de acuerdo con la definición proporcionada por § 8.5.1/1.
Luego viene la prioridad de la inicialización agregada sobre la inicialización de valor. El estándar dice que la inicialización agregada tiene precedencia sobre la inicialización de valor (borrador N3936, § 8.5.4/3, página 201) (énfasis mío)
Lista-inicialización de un objeto o referencia de tipo T se define de la siguiente manera:
- Si T es un agregado, se realiza la inicialización del agregado (8.5.1).
- De lo contrario, si la lista inicializador no tiene elementos y T es un tipo de clase con un constructor predeterminado, el objeto se inicializa por valor.
- [... mas regla...]
(1) Como se solicitó en los comentarios sobre por qué un constructor eliminado no cuenta como definido por el usuario , esto es lo que dice el estándar (borrador N3936, § 8.4.2/5, página 198):
Una función es proporcionada por el usuario si está declarada por el usuario y no está explícitamente predeterminada o eliminada en su primera declaración.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-27 12:09:29
Está bien formado. A
es un agregado1, y, de acuerdo con draft N3936 , una lista de inicializadores vacía utilizada en la inicialización de una lista directa de un agregado resulta en la inicialización agregada:
De § 8.5.4/3 Lista-inicialización [dcl.init.lista]:
Lista-inicialización de un objeto o referencia de tipo T se define de la siguiente manera:
- Si T es un agregado, se realiza la inicialización del agregado (8.5.1).
[ Ejemplo:
struct S2 { int m1; double m2, m3; };
....
S2 s23{}; // OK: default to 0,0,0
....
- ejemplo final ]
....
Los cambios relevantes entre C++11 y C++1y son un cambio en la precedencia de la inicialización de agregado vs. valor para el caso de agregados:
C++11 leads con
List-la inicialización de un objeto o referencia de tipo T se define como sigue:
- Si el la lista del inicializador no tiene elementos y T es una clase escriba con un constructor predeterminado, el objeto se inicializa por valor.
- De lo contrario, si T es un agregado, se realiza la inicialización del agregado (8.5.1)....
Seguido del ejemplo anterior.
C++1y da prioridad a la inicialización agregada:
Lista-inicialización de un objeto o referencia de tipo T se define de la siguiente manera:
- Si T es un agregado, la inicialización del agregado es realizado (8.5.1).
....
- De lo contrario, si la lista del inicializador no tiene elementos y T es un tipo de clase con un constructor predeterminado, el objeto se inicializa por valor.
1 ¿por Qué es A
un agregado?
Es un agregado tanto en C++11 como en C++14.
C++1y:
8.5.1 Agregados [dcl.init.aggr]
Un aggregate es un array o una clase (Cláusula 9) sin constructores (12.1), sin miembros de datos no estáticos privados o protegidos (Cláusula 11), sin clases base (Cláusula 10) y sin funciones virtuales (10.3).
La única parte que no es obvia es si el constructor predeterminado es proporcionado por el usuario o no. No lo es:
En § 8.4.2 [dcl.fct.def.predeterminado]:
Una función es proporcionada por el usuario si está declarada por el usuario y no explícitamente impago o borrado en su primera declaración.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-27 09:51:28