Ich habe über Vorlagenfunktionen gelesen und war durch dieses Problem verwirrt:
#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)
}
Die Ergebnisse sind die gleichen, wenn ich nicht schreibe template void g<double>(double);
.
Ich denke, g<double>
sollte danach instanziiert werden f(double)
, und daher sollte der Anruf bei f
in g
anrufen f(double)
. Überraschenderweise ruft es immer noch f(int)
an g<double>
. Kann mir jemand helfen, das zu verstehen?
Nachdem ich die Antworten gelesen hatte, fand ich heraus, was meine Verwirrung wirklich ist.
Hier ist ein aktualisiertes Beispiel. Es ist größtenteils unverändert, außer dass ich eine Spezialisierung hinzugefügt habe für 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)
}
Verhält sich mit der Benutzerspezialisierung g(1.0)
wie erwartet.
Sollte der Compiler diese Instanziierung nicht automatisch g<double>
an derselben Stelle main()
ausführen (oder sogar danach , wie in Abschnitt 26.3.3 der C ++ - Programmiersprache , 4. Ausgabe beschrieben)?
g(1)
gibti f(int)
für mich. Du hast geschriebend f(double)
. War das ein Tippfehler?