Это вообще не расширение.
VC ++ никогда не реализовывал интерпретацию двух фаз должным образом:
- В точке определения проанализируйте шаблон и определите все независимые имена
- В момент создания экземпляра убедитесь, что шаблон выдает действительный код
VC ++ никогда не реализовывал первый этап ... это неудобно, поскольку это означает не только то, что он принимает код, который не соответствует требованиям, но также и то, что он создает совершенно другой код в некоторых ситуациях.
void foo(int) { std::cout << "int" << std::endl; }
template <class T> void tfoo() { foo(2.0); }
void foo(double) { std::cout << "double" << std::endl; }
int main(int argc, char* argv[])
{
tfoo<Dummy>();
}
С этим кодом:
- совместимые компиляторы будут печатать «int», потому что это было единственное определение, доступное в точке определения шаблона, и разрешение
foo
не зависит от T
.
- VC ++ напечатает "double", потому что он никогда не беспокоился о фазе 1
Это может показаться глупым в том, что касается различий, но если вы подумаете о количестве включений, которые у вас есть в большой программе, есть риск, что кто-то введет перегрузку после кода вашего шаблона ... и BAM: /