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 ).