c++ - tres - preguntas valorativas de un texto
¿Por qué no se define `std:: initializer_list` como un tipo literal? (1)
Esta es una continuación de esta pregunta: ¿es legal declarar un objeto constexpr initializer_list? .
Desde C ++ 14, la clase std::initializer_list
tiene todos sus métodos marcados con constexpr
. Parece natural poder inicializar una instancia haciendo constexpr std::initializer_list<int> list = {1, 2, 3};
pero Clang 3.5 se queja de que la list
no se inicializa con una expresión constante. Como dyp señaló en un comentario , cualquier requisito para que std::initializer_list
sea un tipo literal parece haberse desvanecido de las especificaciones.
¿De qué sirve tener una clase completamente definida como constexpr si ni siquiera podemos inicializarla como tal? ¿Es un descuido en el estándar y se solucionará en el futuro?
El comité estándar parece pretender que initializer_list
sea un tipo literal. Sin embargo, no parece ser un requisito explícito, y parece ser un error en el estándar.
Del § 3.9.10.5:
Un tipo es un tipo literal si es:
- un tipo de clase (Cláusula 9) que tiene todas las siguientes propiedades:
- - tiene un destructor trivial,
- - es un tipo agregado (8.5.1) o tiene al menos un constructor constexpr o una plantilla de constructor que no es un constructor de copia o movimiento, y
- - todos sus miembros de datos no estáticos y clases base son de tipos literales no volátiles.
Del § 18.9.1:
namespace std {
template<class E> class initializer_list {
public:
/* code removed */
constexpr initializer_list() noexcept;
// No destructor given, so trivial
/* code removed */
};
}
Esto satisface los requisitos primero y segundo.
Para el tercer requisito, sin embargo:
De § 18.9.2 (énfasis mío):
Un objeto de tipo
initializer_list<E>
proporciona acceso a una matriz de objetos de tipoconst E
[Nota: un par de punteros o un puntero más una longitud serían representaciones obvias parainitializer_list
.initializer_list
se usa para implementar listas de inicializadores como se especifica en 8.5.4. Copiar una lista de inicializadores no copia los elementos subyacentes.
-Finalizar nota]
Por lo tanto, no es necesario que los miembros privados de la implementación de initializer_list
sean tipos literales no volátiles; sin embargo, como mencionan que creen que un par de punteros o un puntero y una longitud serían la "representación obvia", probablemente no consideraron que alguien pudiera poner algo no literal en los miembros de initializer_list
.
Diría que es a la vez un error en clang y el estándar.