initialize enclosed brace c++ c++11 language-lawyer initializer-list constexpr

c++ - enclosed - ¿Es legal declarar un objeto constexpr initializer_list?



c++ 11 initializer list (1)

Como una pregunta que surgió durante la discusión de esta pregunta de SO :

¿Es legal, tal vez con N3471 , declarar un objeto constexpr std::initializer_list ? Ejemplo:

constexpr std::initializer_list<int> my_list{};

Por qué creo que puede no ser legal: initializer_list debería ser de tipo literal; ¿Pero hay alguna garantía de que sea un tipo literal?

Citas de N3485.

[dcl.constexpr] / 9:

Un especificador constexpr utilizado en una declaración de objeto declara que el objeto es const. Dicho objeto tendrá un tipo literal y se inicializará.

requisitos de tipos literales, [basic.types] / 10, tipos de clase de sub-viñetas:

  • un tipo de clase (Cláusula 9) que tiene todas las siguientes propiedades:
    • tiene un destructor trivial,
    • cada llamada de constructor y expresión completa en los inicializadores con o sin llave para los miembros de datos no estáticos (si existen) es una expresión constante (5.19),
    • es un tipo agregado (8.5.1) o tiene al menos un constructor constexpr o plantilla de constructor que no es un constructor de copia o movimiento, y
    • todos sus miembros de datos no estáticos y sus clases base son de tipos literales no volátiles.

Puntos de bonificación;) por contestar si

constexpr std::initializer_list<int> my_list = {1,2,3,4,5};

Es legal (con referencias). Aunque creo que esto está cubierto por lo anterior + [dcl.init.list] / 5


Actualización: la situación se complicó un poco más después de que la resolución del CWG DR 1684 eliminara el requisito que se cita a continuación. Puede encontrar más información en esta discusión en la lista de correo de discusión estándar y en la pregunta relacionada ¿ Por qué no se define `std :: initializer_list` como un tipo literal?

[decl.constexpr] / 8:

Un especificador constexpr para una función miembro no estática que no es un constructor declara que esa función miembro es const (9.3.1). [...] La clase de la cual esa función es un miembro será un tipo literal (3.9).

Por lo tanto, los cambios de N3471 garantizan que std::initializer_list será un tipo literal.

Tenga en cuenta que el constexpr ctor solo no requiere que std::initializer_list sea ​​un tipo literal, vea [dcl.constexpr] / 4 + 8. Nota al constexpr : un objeto de tipo no literal con constexpr ctor se puede inicializar durante la inicialización constante [basic.start.init] / 2] (parte de la inicialización estática , realizada antes de cualquier inicialización dinámica ).