c++ c++11 language-lawyer uniform-initialization

c++ - T v{} inicialización



c++11 language-lawyer (2)

Estoy leyendo el estándar C ++ 11, pero no puedo averiguar si

T x{};

está inicializado por valores o inicializado por defecto (almacenamiento automático). Dice bastante claramente que:

10 Un objeto cuyo inicializador es un conjunto vacío de paréntesis, es decir, (), se inicializará con valores.

Y eso

11 Si no se especifica un inicializador para un objeto, el objeto se inicializa por defecto;

Pero todo lo que puedo encontrar sobre T x{}; es eso:

La inicialización que se produce en las formas T x (a); T x {a}; así como en las nuevas expresiones (5.3.4), las expresiones static_cast (5.2.9), las conversiones de tipo de notación funcional (5.2.3) y los inicializadores de base y miembro (12.6.2) se denominan inicialización directa.

y

Si el inicializador es una lista-iniciada con paréntesis (no entre paréntesis), el objeto o la referencia se inicializa en la lista (8.5.4).

Soy nuevo en el nivel de lectura de los estándares. ¿Alguien me puede apuntar en la dirección correcta?


Aunque Matt McNabb ya ha cubierto esto, agregaré que si tiene problemas para navegar a través del estándar, no está de más revisar la referencia de cpp . Su sección en la inicialización de la lista lo desglosa bastante bien.

Esencialmente, como dice su cita estándar, T x{}; se refiere a un

Inicialización de una variable nombrada con una lista de expresiones o listas anidadas entre corchetes ( braced-init-list ).

Y:

Los efectos de la inicialización de lista de un objeto de tipo T son:

  • Si la lista-iniciada con paréntesis está vacía y T es un tipo de clase con un constructor predeterminado, se realiza la inicialización del valor.

[...]

  • De lo contrario, si la lista-iniciada con corchetes no tiene elementos, T se inicializa con valores.

Esto está cubierto por su cita:

Si el inicializador es una lista-iniciada con paréntesis (no entre paréntesis), el objeto o la referencia se inicializa en la lista (8.5.4).

Saltando hasta 8.5.4 inicialización de lista. Aquí he parafraseado / omitido algunos puntos que no pertenecen al caso de T x{} :

La inicialización de lista de un objeto o referencia de tipo T se define de la siguiente manera:

  • Si T es un agregado, se realiza la inicialización agregada (8.5.1).
  • De lo contrario, si la lista de inicializadores no tiene elementos y T es un tipo de clase con un constructor predeterminado, el objeto se inicializa con valor
  • De lo contrario, si T es una especialización de std::initializer_list<E> [...]
  • De lo contrario, [si la lista no está vacía y coincide con un constructor]
  • De lo contrario, [si la lista tiene un solo elemento]
  • De lo contrario, [si T es un tipo de referencia]
  • De lo contrario, si la lista de inicializadores no tiene elementos, el objeto se inicializa con valores.
  • De lo contrario, el programa está mal formado.

El primer punto, la inicialización agregada fue también en C ++ 03; en ese caso T x{}; es lo mismo que T x = {}; .

Para el segundo punto "T es un tipo de clase con un constructor predeterminado", se inicializa con un valor que significa llamar al constructor predeterminado.

Si T es un tipo primitivo, se aplica el punto segundo a último y se vuelve a inicializar el valor .

Volviendo al caso de inicialización agregada , en 8.5.1 / 7 hay:

Si hay menos cláusulas de inicialización en la lista que miembros en el agregado, entonces cada miembro que no se inicialice explícitamente se inicializará desde su inicializador de corsé o igual o, si no hay un inicializador de corsé o igual, de una lista de inicialización vacía (8.5.4).

El inicializador de corsé o igual se refiere a un inicializador proporcionado en línea en la definición de clase. Si eso no está presente, entonces se inicializa como si el miembro se hubiera inicializado con {} (por lo tanto, esta lógica se aplica recursivamente para cada miembro agregado).

Por ejemplo,

struct T { int a; };

entonces T x {}; conduce a a inicialización como si fuera int a{}; , que es la inicialización de valores, ya que int es un tipo primitivo.