Я читав про функції шаблону і заплутався у цій проблемі:
#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>
що після цього слід створити екземпляри 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)
. Це була друкарня?