Uso incompleto da classe no modelo

Estou muito surpreso que, em várias versões de amostra do g ++, o seguinte seja compilado sem erro ou aviso:

// Adapted from boost::checked_delete()
template <class T> inline void assert_complete()
{
  typedef char type_must_be_complete[ sizeof(T) ? 1 : -1 ];
  (void) sizeof(type_must_be_complete);
}

class X;

void f()
{
  assert_complete<X>();
}

class X {};

int main() {}

Se a definição deX está ausente ou em uma unidade de tradução diferente, eu recebo erros.

Mas no programa como acima, não é a definição def o único ponto de instanciação do meu modelo? E não é a incompletude deX naquele momento da instanciação um erro semântico?

O padrão (C ++ 03 e / ou C ++ 11 rascunho) chama esse programa de bem formado, mal formado, mal formado, mas o diagnóstico não é necessário ou um comportamento indefinid

Edit: @David Rodriguez - A dribeas relata que clang ++, comeau e Visual Studio 2010 também aceitam código semelhant

questionAnswers(2)

yourAnswerToTheQuestion