Ответ 1
Программа плохо сформирована, потому что вы не инициализируете x
, если вы измените определение на:
literal_array<T, n+m> x = {{0}};
clang
больше не жалуется и компилируется без ошибок. Другим решением было бы создание консректоров constexpr.
Мы можем найти это в разделе черновик проекта 7.1.5
Параграф 3 описания constexpr, который гласит:
Определение функции
constexpr
должно удовлетворять следующему Ограничения:
и включает следующую марку:
его тело функции должно быть
= delete
,= default
, или составной оператор, который не содержит
который содержит эту пулю (акцент мой):
определение переменной нелитерального типа или статического или потока время хранения или для которого не выполняется инициализация.
а затем мы имеем следующий пример:
constexpr int uninit() {
int a; // error: variable is uninitialized
return a;
}
Жалоба о времени жизни x
, похоже, не основана на черновом проекте. Правильная причина, насколько я могу судить, должна быть чем-то вроде object is not initialized
.
Соответствующая цитата из проекта стандарта на время жизни объекта будет секцией 3.8
Object lifetime paragraph 1, которая гласит:
Время жизни объекта - это свойство времени выполнения объекта. считается, что объект имеет нетривиальную инициализацию, если он имеет класс или совокупный тип, и он или один из его членов инициализируется конструктор, отличный от тривиального конструктора по умолчанию. [ Заметка: инициализация тривиальным конструктором copy/move является нетривиальной инициализация. - end note] Наступает время жизни объекта типа
T
когда:
- получено хранилище с правильным выравниванием и размером для типа
T
и- Если объект имеет нетривиальную инициализацию, его инициализация завершена.
На всякий случай, когда я отсутствовал, я также проверил с помощью std:: is_trivial:
std::cout << std::boolalpha << std::is_trivial<literal_array<int, 3>>::value << std::endl ;
и результат, как ожидалось в true
,
Обновить
Я написал отчет об ошибках для этого, и ответ включает в себя следующее утверждение:
[...] Проблема в том, что мы еще не реализуем подразумеваемое правило, что такую функцию нельзя вызывать в постоянном выражении.