Ответ 1
Стандартный комитет, похоже, намерен на initializer_list
быть буквальным типом. Однако это не похоже на явное требование и, кажется, является ошибкой в стандарте.
Из § 3.9.10.5:
Тип - это буквальный тип, если он:
- тип класса (раздел 9), который обладает всеми следующими свойствами:
- - он имеет тривиальный деструктор,
- - это совокупный тип (8.5.1) или имеет хотя бы один конструктор конструктора или конструктора constexpr, который не является конструктором копирования или перемещения, и
- - все его нестатические элементы данных и базовые классы являются нелетучими литералами.
Из § 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 */
};
}
Это удовлетворяет первым и вторым требованиям.
Для третьего требования:
Из § 18.9.2 (акцент мой):
Объект типа
initializer_list<E>
обеспечивает доступ к массиву объектов типаconst E
. [Примечание: Пара указателей или указатель плюс длина будут очевидными представлениями дляinitializer_list
.initializer_list
используется для реализации списков инициализаторов, как указано в 8.5.4. Копирование списка инициализаторов не копирует основные элементы.
-end note]
Таким образом, для частных членов реализации initializer_list
нет необходимости использовать типы нелетучих литералов; однако, поскольку они упоминают, что они считают, что пара указателей или указатель и длина будут "очевидным представлением", они, вероятно, не считают, что кто-то может помещать что-то нелитеральное в члены initializer_list
.
Я бы сказал, что это как ошибка в clang, так и стандартная, возможно.