我有以下代码:
#include <iostream>
template <typename T>
void f (T) { std::cout << "f(T)" << std::endl; }
template <typename T>
void f (bool) { std::cout << "f(bool)" << std::endl; }
int main ( )
{
f(true); // #1 prints f(T)
f<bool>(true); // #2 prints f(bool)
}
#1
行调用f(T)
,而#2
行调用f(bool)
。为什么会这样?选择重载模板函数的规则是什么?
更新
我了解到,在第一次调用中,编译器无法在尝试调用第二个函数时推断出
T
,因此选择了第一个。在第二个调用中,第二个功能被认为是在gcc上更好的匹配,而第一个功能是在VS2013下选择的。谁在这里做正确的事?顺便说一下,我仍然对该过程的完整描述感兴趣。
最佳答案
未特化的功能模板也称为基础基本模板。 基本模板可以是专门的。看看在不同情况下会调用哪个的重载规则非常简单,至少在较高级别上如此:
如果要自定义函数基础模板并希望该自定义参与重载解析(或者在完全匹配的情况下始终使用),则使其成为普通的旧函数,而不是专门化的函数。并且,如果您确实提供了重载,请避免也提供特化知识。
上面是和 Herb Sutter的this帖子的摘录,在突出显示的项目符号中,您可以看到问题的根源
编辑
如果您尝试(不要这样做)在Visual Studio 2012中使用上述代码,则会得到
如here所述,这是因为
而以下行应归咎于
f(true); // #1 prints f(T)
因此答案中的歧义没有保证的解决方案