После прочтения ответа на этот вопрос я все еще задаю вопрос.Ответ говорит о расположении точки создания экземпляра, как определено в [temp.point], но не оценивается, требуется ли создание экземпляров.
[temp.inst] указывает, когда шаблон функциитребуется конкретизация специализации, общее правило:
Реализация не должна неявно создавать экземпляр шаблона функции, шаблона переменной, шаблона элемента, не виртуальной функции-члена, класса-члена, [...], , если такое создание не требуется.
Более того, в некоторых параграфах этого раздела стандарта создание объявления и определение определения рассматриваются отдельно.
Давайте рассмотрим этот код:
static void Yeap0(int);
template <class T>
void Yeap(T a){
Yop(a);
}
template <class T>
auto Yeap2(T a){
Yop(a);
return 0;
}
namespace x{
struct y{};
}
int main() {
Yeap0(0);//ok no definition required here
x::y ax{};
Yeap(ax); //the declaration is sufficient,
Yeap2(ax); //need to deduce auto => definition required
//compilation error
return 0;
}
namespace x{
void Yop(y){}
}
static void Yeap0(int){}
Gcc, Clang и MSVC выдают только ошибку для Yeap2(ax)
, жалуясь, что Yop
не определен в момент создания Yeap2.
Но эта ошибка не генерируется для Yeap(ax)
.Исходя из базовых соображений, это кажется логичным, необходимо только объявление, так как для функции non template Yeap0
.
Но лекция [temp.inst] / 4 позволила мне озадачиться.Можно понять, что создание экземпляра Yeap
также требуется.Но кажется, что компиляторы выбрали более умный путь.
Является ли поведение компиляторов расширением?
Примечание. Я не приму ответ "нет необходимости в диагностике".Это было бы оскорблением для интеллекта: можно ли поверить, что 3 компилятора позаботились о выключении диагностики для случая, подобного Yeap(ax)
, но не для Yeap2(ax)
?