Ожидание разных типов в зависимости от момента создания - PullRequest
0 голосов
/ 10 сентября 2018

Я ожидаю, что NDR плохо сформирован, но, похоже, нет: - (

#include <type_traits>

template <typename T, typename Enabler = void>
struct is_complete : std::false_type {};

template <typename T>
struct is_complete<T, std::void_t<decltype(sizeof(T) != 0)>> : std::true_type {};

class X;

static_assert(!is_complete<X>::type{}); // incomplete type

class X {};

static_assert(!is_complete<X>::type{}); // complete, but already instantiated

Демо

Примечание :Предполагая, что sizeof(T) != 0 действителен для черт завершенности (поскольку ни один тип не может иметь sizeof(T) == 0, использование другой константы заставит найти лучшее имя для черт :-))

Это вариант кода из Является ли специализация неявно созданной, если она уже была неявно создана? , где программа была объявлена ​​некорректной программой, Диагностика не требуется (NDR), как метод is_complete_helper<X>::test<X>имеет 2 различных значения в зависимости от точек реализации.

Ссылки, которые, кажется, близки, чтобы сделать программу плохо сформированной, но не, как я понимаю:

интерпретация такой конструкции в гипотетической реализации отличается от интерпретации соответствующей конструкции в любой реальной реализации шаблона.

Специализация для шаблона функции, шаблона функции-члена или функции-члена или статического члена данных шаблона класса может иметь несколько точек создания экземпляров в единице перевода,и в дополнение к пунктам создания экземпляров, описанным выше, для любой такой специализации, которая имеет точку создания экземпляров в пределах единицы перевода, конец единицы перевода также считается точкой создания экземпляров.Специализация для шаблона класса имеет не более одной точки создания экземпляра в единице перевода.Специализация для любого шаблона может иметь точки создания экземпляров в нескольких единицах перевода.Если две разные точки инстанцирования придают шаблону специализации разные значения в соответствии с правилом одного определения, программа некорректна, диагностика не требуется.

Я не прав?или, к сожалению, эта программа верна.

1 Ответ

0 голосов
/ 10 сентября 2018

Я ожидаю, что следующее недействительное 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) является допустимым выражением.

...