Предположим, у меня есть следующий фрагмент кода:
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 выдает ошибку «неполный тип».