ฉันอ่านเกี่ยวกับฟังก์ชั่นเทมเพลตและสับสนกับปัญหานี้:
#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)
}
template void g<double>(double);
ผลลัพธ์ที่ได้จะเหมือนกันถ้าผมไม่ได้เขียน
ผมคิดว่าg<double>
ควรจะ instantiated หลังf(double)
และดังนั้นจึงเรียกร้องให้f
ในควรจะเรียกg
f(double)
ที่น่าแปลกใจก็ยังคงเรียกร้องในf(int)
g<double>
ใครช่วยฉันเข้าใจสิ่งนี้ได้บ้าง
หลังจากอ่านคำตอบแล้วฉันก็พบว่าความสับสนของฉันคืออะไร
นี่คือตัวอย่างที่อัปเดต ส่วนใหญ่จะไม่เปลี่ยนแปลงยกเว้นว่าฉันได้เพิ่มความเชี่ยวชาญสำหรับ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)
}
ด้วยความเชี่ยวชาญของผู้ใช้g(1.0)
จะทำงานตามที่คาดไว้
คอมไพเลอร์ไม่ควรทำอินสแตนซ์เดียวกันนี้โดยอัตโนมัติg<double>
ในที่เดียวกัน (หรือแม้กระทั่งหลังจากmain()
นั้นตามที่อธิบายไว้ในส่วนที่ 26.3.3 ของภาษาการเขียนโปรแกรม C ++รุ่นที่ 4)
g(1)
ให้i f(int)
ฉันd f(double)
ที่คุณเขียน นี่เป็นตัวพิมพ์ผิดหรือเปล่า?