Je lisais sur les fonctions de modèle et je suis devenu confus par ce problème:
#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)
}
Les résultats sont les mêmes si je n'écris pas template void g<double>(double);
.
Je pense g<double>
à instancier après f(double)
, et donc l'appel à f
en g
devrait appeler f(double)
. Étonnamment, il appelle encore f(int)
à g<double>
. Quelqu'un peut-il m'aider à comprendre cela?
Après avoir lu les réponses, j'ai compris ce qu'est vraiment ma confusion.
Voici un exemple mis à jour. Il est pratiquement inchangé sauf que j'ai ajouté une spécialisation pour 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)
}
Avec la spécialisation utilisateur, g(1.0)
se comporte comme je m'y attendais.
Le compilateur ne doit-il pas automatiquement effectuer cette même instanciation g<double>
au même endroit (ou même après main()
, comme décrit dans la section 26.3.3 du langage de programmation C ++ , 4e édition)?
g(1)
,,i f(int)
me donne . Vous avez écritd f(double)
. C'était une faute de frappe?