Estaba leyendo sobre las funciones de plantilla y me confundí con este problema:
#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)
}
Los resultados son los mismos si no escribo template void g<double>(double);
.
Creo que g<double>
debería crearse una instancia después f(double)
y, por lo tanto, la llamada a f
in g
debería llamar f(double)
. Sorprendentemente, todavía se llama f(int)
en g<double>
. ¿Alguien puede ayudarme a entender esto?
Después de leer las respuestas, descubrí cuál es realmente mi confusión.
Aquí hay un ejemplo actualizado. En su mayoría no ha cambiado, excepto que agregué una especialización para 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)
}
Con la especialización del usuario, se g(1.0)
comporta como esperaba.
¿Debería el compilador no hacer automáticamente esta misma instanciación g<double>
en el mismo lugar (o incluso después main()
, como se describe en la sección 26.3.3 de The C ++ Programming Language , cuarta edición)?
g(1)
, dai f(int)
por mí. Usted escribiód f(double)
. ¿Era esto un error tipográfico?