Является ли законным объявление объекта constexpr initializer_list?
В качестве вопроса, который возник при обсуждении этого SO-вопроса:
Является ли это законным, возможно, с N3471, чтобы объявить объект constexpr std::initializer_list
? Пример:
constexpr std::initializer_list<int> my_list{};
Почему я думаю, что это может быть не законным: initializer_list
должен быть буквальным типом; но есть ли какие-либо гарантии, что это буквальный тип?
Цитаты из N3485.
[dcl.constexpr]/9:
Спецификатор constexpr, используемый в объявлении объекта, объявляет объект как const. Такой объект должен иметь буквальный тип и должен быть инициализирован.
литеральные типы типов, [basic.types]/10, типы подпункта:
- тип класса (раздел 9), который имеет все следующие свойства:
- он имеет тривиальный деструктор,
- каждый вызов конструктора и полноэкранное выражение в элементарных элементах для нестатических данных (если они есть) является константным выражением (5.19),
- это тип агрегата (8.5.1) или имеет хотя бы один конструктор конструктора или конструктора constexpr, который не является конструктором копирования или перемещения, и
- все его нестатические элементы данных и базовые классы являются нелетучими литералами.
Бонусные точки;) для ответа, если
constexpr std::initializer_list<int> my_list = {1,2,3,4,5};
является законным (со ссылками). Хотя я думаю, что это описано выше + [dcl.init.list]/5
Ответы
Ответ 1
Обновление: Ситуация немного усложнилась после того, как разрешение CWG DR 1684 удалило указанное требование ниже. Более подробную информацию можно найти в эту дискуссию в списке рассылки std-обсуждения и в соответствующем вопросе Почему не `std:: initializer_list` определяется как тип литерала?
[decl.constexpr]/8:
Спецификатор constexpr для нестатической функции-члена, которая не является конструктором, объявляет, что функция-член является константой (9.3.1). [...] Класс, членом которого является член, должен быть буквальный тип (3.9).
Следовательно, изменения гарантии N3471 std::initializer_list
будут буквальными.
Обратите внимание, что constexpr
ctor не требует, чтобы std::initializer_list
был литеральным типом, см. [dcl.constexpr]/4 + 8. Замечание: объект нелитерального типа с constexpr
ctor может быть инициализирован при постоянной инициализации [basic.start.init]/2] (часть статической инициализации, выполняемая до любой динамической инициализации).