C ++ 20 draft [concept.default.init] не определяет точно default_initializable
template<class T>
concept default_initializable = constructible_from<T> &&
requires { T{}; } &&
is-default-initializable <T>; // exposition-only
и описывает, что инициализируется по умолчанию следует использовать со следующими словами:
Для типа T
, is-default-initializable истинно тогда и только тогда, когда определение переменной
T t;
хорошо сформировано для некоторой придуманной переменной t; в противном случае это ложь. Проверка доступа выполняется, как если бы в контексте, не связанном с T. Учитывается только действительность непосредственного контекста инициализации переменной.
На cppreference мы находим следующее предложение для возможная реализация:
template<class T>
concept default_initializable =
std::constructible_from<T> &&
requires { T{}; } &&
requires { ::new (static_cast<void*>(nullptr)) T; };
Оператор размещения-new, вызываемый с аргументом nullptr
, приводит к неопределенному поведению.
9) Вызывается новое выражение стандартного размещения одного объекта. Реализация стандартной библиотеки не выполняет никаких действий и возвращает ptr без изменений. Поведение не определено, если эта функция вызывается через выражение размещения new, а ptr является нулевым указателем.
У меня вопрос: действительно ли предложенная возможная реализация действительна? С одной стороны, я думаю, что нет, потому что задействовано выражение, которое демонстрирует неопределенное поведение. С другой стороны, я думаю, что да, потому что это выражение встречается в неоцененном контексте и, следовательно, может не иметь четко определенного поведения (?) И просто должно быть синтаксически правильным. Но я не могу найти четких доказательств того или другого.
Второй вопрос: если последнее окажется правдой, то почему эта новая конструкция размещения удовлетворяет стандартному требованию, что T t;
должно быть хорошо- сформирован? Мне это кажется странным хаком, потому что ни простые, ни сложные требования не дают возможности требовать T t;
точно. Но почему это работает?