Я читал о шаблонных функциях и запутался в этой проблеме:
#include <iostream>
void f(int) {
std::cout << "f(int)\n";
}
template<typename T>
void g(T val) {
std::cout << typeid(val).name() << " ";
f(val);
}
void f(double) {
std::cout << "f(double)\n";
}
template void g<double>(double);
int main() {
f(1.0); // f(double)
f(1); // f(int)
g(1.0); // d f(int), this is surprising
g(1); // i f(int)
}
Результаты будут такими же, если я не напишу template void g<double>(double);
.
Я думаю, что g<double>
должен быть создан после f(double)
, и, следовательно, вызов f
в g
должен позвонить f(double)
. Удивительно, но до сих пор вызывает f(int)
в g<double>
. Может ли кто-нибудь помочь мне понять это?
Прочитав ответы, я понял, в чем заключается моя путаница.
Вот обновленный пример. В основном это не изменилось, за исключением того, что я добавил специализацию для g<double>
:
#include <iostream>
void f(int){cout << "f(int)" << endl;}
template<typename T>
void g(T val)
{
cout << typeid(val).name() << " ";
f(val);
}
void f(double){cout << "f(double)" << endl;}
//Now use user specialization to replace
//template void g<double>(double);
template<>
void g<double>(double val)
{
cout << typeid(val).name() << " ";
f(val);
}
int main() {
f(1.0); // f(double)
f(1); // f(int)
g(1.0); // now d f(double)
g(1); // i f(int)
}
С пользовательской специализацией g(1.0)
ведет себя как я ожидал.
Разве компилятор не должен автоматически выполнять эту же реализацию для g<double>
того же самого места (или даже после main()
, как описано в разделе 26.3.3 языка программирования C ++ , 4-е издание)?
g(1)
, даетi f(int)
за меня. Вы написалиd f(double)
. Это была опечатка?