在下面的代码中,主函数使用普通函数而不是模板函数。
#include <iostream>
using namespace std;
template <class T>
void num(T t){cout<<"T : "<<t;}
void num(int a){cout<<"wT : "<<a;}
int main()
{
num(5);
return 0;
}
这背后的可能原因是什么?
在下面的代码中,主函数使用普通函数而不是模板函数。
#include <iostream>
using namespace std;
template <class T>
void num(T t){cout<<"T : "<<t;}
void num(int a){cout<<"wT : "<<a;}
int main()
{
num(5);
return 0;
}
这背后的可能原因是什么?
看看 Herb Sutter 的优秀文章“为什么不专门化函数模板?”
去引用:
“最后,我们只关注函数模板,考虑重载规则,看看在不同的情况下调用了哪些规则。规则很简单,至少在高层次上,可以表示为经典的二分类系统:
非模板函数是一等公民。与参数类型以及任何函数模板相匹配的普通旧非模板函数将被选择,而不是其他情况相同的函数模板。
如果没有至少一样好的一等公民可供选择,那么接下来参考二等公民的功能基础模板。根据一组相当神秘规则:
如果很明显有一个“最专业的”功能基础模板,那么就会使用那个模板。如果该基本模板恰好专门用于正在使用的类型,则将使用该专门化,否则将使用以正确类型实例化的基本模板。
否则,如果“最专业”的函数基模板存在平局,则该调用是模棱两可的,因为编译器无法确定哪个是更好的匹配。程序员必须做一些事情来限定调用并说出需要哪个调用。
否则,如果没有可以匹配的函数基模板,则调用是错误的,程序员将不得不修复代码。”
在您的代码示例中,正如 David Z. 所指出的那样,void num(int a)
将选择非模板函数,因为它在第一条规则中匹配。任何其他功能模板只有在它们更匹配时才会被考虑。
在这种情况下,要调用模板方法,您需要使用num<int>(5)
而不是显式调用该方法num(5)
。尽管编译器可以推断,但非泛型方法优于泛型方法。您可以在此处查看此行为http://ideone.com/ccDJP。