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!

Author: zneak, 2014-05-27

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.

 30
Author: user703016,
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.

 19
Author: juanchopanza,
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