Saya membaca tentang fungsi templat dan menjadi bingung oleh masalah ini:
#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)
}
Hasilnya sama jika saya tidak menulis template void g<double>(double);
.
Saya pikir g<double>
harus instantiated setelah f(double)
, dan karena itu panggilan f
masuk g
harus memanggil f(double)
. Anehnya, masih panggilan f(int)
di g<double>
. Adakah yang bisa membantu saya memahami ini?
Setelah membaca jawaban, saya mencari tahu apa sebenarnya kebingungan saya.
Ini adalah contoh yang diperbarui. Sebagian besar tidak berubah kecuali bahwa saya menambahkan spesialisasi untuk 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)
}
Dengan spesialisasi pengguna, g(1.0)
berperilaku seperti yang saya harapkan.
Haruskah kompiler tidak secara otomatis melakukan instantiasi yang sama ini g<double>
di tempat yang sama (atau bahkan setelah main()
, seperti yang dijelaskan dalam bagian 26.3.3 dari Bahasa Pemrograman C ++ , edisi ke-4)?
g(1)
,, memberii f(int)
saya. Anda menulisd f(double)
. Apakah ini salah cetak?