Рассмотрим следующий небольшой фрагмент кода:
#include <iostream>
template<class T>
int test();
int main()
{
std::cout << test<int>() << "\n";
}
// POI for test<int>() should be right here
template<class T>
int test()
{
return 0;
}
Живой пример, который компилирует и печатает 0 для Clang и g++.
Здесь черновик проекта в момент создания шаблонов функций
14.6.4.1 Точка инстанцирования [temp.point]
1 Для специализации шаблона функции, специализации шаблона функции-члена или специализации для член или статический член данных шаблона класса, если специализация неявно создается потому что на него ссылаются из другой специализированной специализации и контекст, с которого он ссылается зависит от параметра шаблона, точкой инстанцирования специализации является точка создание специализированной специализации. В противном случае точка инстанцирования для такой специализации сразу следует за объявлением или определением области пространства имен, которое относится к специализации.
Vandevoorde и Josuttis могут сказать следующее:
На практике большинство компиляторов откладывают фактическое noninline шаблоны функций до конца единицы перевода. Эта эффективно перемещает POI соответствующего шаблона специализации до конца единицы перевода. Намерение разработчики языка С++ были для этого правильной реализацией техники, но стандарт не делает этого ясно.
Вопрос: являются несоответствия Clang/g++, поскольку они задерживают POI до конца единицы перевода?