Stavo leggendo le funzioni del modello e mi sono confuso con questo 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)
}
I risultati sono gli stessi se non scrivo template void g<double>(double);
.
Penso che g<double>
dovrebbe essere istanziato dopo f(double)
, e quindi la chiamata a f
in g
dovrebbe chiamare f(double)
. Sorprendentemente, si chiama ancora f(int)
in g<double>
. Qualcuno può aiutarmi a capire questo?
Dopo aver letto le risposte, ho capito qual è la mia confusione.
Ecco un esempio aggiornato. È per lo più invariato tranne per il fatto che ho aggiunto una specializzazione per 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 specializzazione dell'utente, g(1.0)
si comporta come mi aspettavo.
Il compilatore non dovrebbe fare automaticamente questa stessa istanza g<double>
nello stesso posto (o anche dopo main()
, come descritto nella sezione 26.3.3 di The C ++ Programming Language , 4th edition)?
g(1)
dài f(int)
. Hai scrittod f(double)
. Era un errore di battitura?