Предположим, у меня есть следующий фрагмент кода:
template <class T>
class Bar
{
// static_assert(sizeof(T) > 0); // (1)
public:
void method()
{
static_assert(sizeof(T) > 0); // (2)
}
};
class Foo; // (3)
template class Bar<Foo>; // (4)
class Foo{}; // (5)
Если мы раскомментируем строку (1), мы получим ошибку во время компиляции «неполный тип T», и, похоже, все ясно: class Bar
инстанцирование запускается с помощью (4), и в этот момент class Foo
объявляется только форвардом (3) и еще не определено (5).
Но если строка (1) закомментированазатем этот код компилируется без ошибок, и это меня смущает: (4) является явным определением экземпляра шаблона и заставляет компилятор генерировать код void method()
, а строка (2) также должна генерировать ту же ошибку, так какопределение Foo
сделано позже в (5).
Что мне не хватает, почему компилируется код из фрагмента?
ОБНОВЛЕНИЕ : код компилируется вGCC 8.2.0 и MSVC 19.16.27025.1, но в Clang 7.0.0 выдает ошибку «неполного типа».