Ах да, я понимаю вашу точку зрения; Похоже, я, вероятно, неправильно истолковал спецификации. Однако [temp.arg.type] утверждает, что «аргумент типа шаблона может быть неполным типом», что, я полагаю, позволяет ему использовать завершенный тип, определенный позже в модуле перевода.

нь удивлен, что на различных выборочных версиях g ++ следующие компиляции без ошибок и предупреждений:

// 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() {}

Если определениеX отсутствует или в другом модуле перевода, я получаю ошибки.

Но в программе, как указано выше, нет определенияf единственная точка инстанцирования моего шаблона? И не является ли незавершенностьX в этом моменте семантической ошибки?

Стандарт (C ++ 03 и / или C ++ 11 Draft) называет эту программу правильно сформированной, плохо сформированной, плохо сформированной, но не требующей диагностики, или неопределенным поведением?

Редактировать: @David Rodriguez - dribeas сообщает, что clang ++, comeau и Visual Studio 2010 также принимают аналогичный код.

Ответы на вопрос(2)

Ваш ответ на вопрос