Я ожидаю, что следующее недействительное NDR, но, похоже, нет: - (
Вы не можете использовать тот факт, что программа компилирует (и запускает) в качестве доказательства того, что онане плохо сформированный, отчет о недоставке. Точно так же, как вы не можете использовать, казалось бы, корректный вывод программы, чтобы продемонстрировать, что она не проявляет неопределенного поведения.
Тем не менее, соответствующее правило здесь - [temp.point] / 8 :
Специализация для шаблона класса имеет не более одной точки создания экземпляра в единице перевода. Специализация для любого шаблона может иметь точки создания экземпляра в множественном переводе.единиц. Если две разные точки инстанцирования придают специализации шаблона разные значения в соответствии с правилом одного определения, программа плохо сформирована, диагностика не требуется.
У нас есть только одна точка инстанцированияis_complete<X>
: что прямо перед первым static_assert
. Итак, это «хорошо» - это, возможно, сбивает с толку и плохо, но оно правильно сформировано.
Но, однако, если мы разделим это на части:
// a.cpp
struct X;
static_assert(!is_complete<X>::value);
// b.cpp
struct X { };
static_assert(is_complete<X>::value);
Теперь это плохо сформировано, диагностика не требуется.
Обратите внимание, вам не нужно sizeof(T) != 0
.Просто sizeof(T)
в порядке.Вы не можете взять sizeof
неполного типа, поэтому вам просто нужно проверить, что sizeof(T)
является допустимым выражением.