我有一个正常工作的重载功能。 (例子中的f)。当我将它转换为同一件事的模板版本时,它总是通过调用T&版本,永远不会是T *。 (在示例中为t)当我创建模板函数的非const版本时,它按预期工作。 (示例中为t2)VS2010和g ++ 4.6.2都会出现这种情况。促销对const规则是否不同,或者这是某种错误。
#include <iostream>
using namespace std;
int f(const int&x){return 1;}
int f(const int*x){return 2;}
template <class T> int t(const T &x){return 3;}
template <class T> int t(const T *x){return 4;}
template <class T> int t2(T &x){return 5;}
template <class T> int t2(T *x){return 6;}
int main(int argc, char ** argv){
int x=0;
cout<<f(x)<<endl;
cout<<f(&x)<<endl;
cout<<t(x)<<endl;
cout<<t(&x)<<endl;
cout<<t2(x)<<endl;
cout<<t2(&x)<<endl;
return 0;
}
输出
1
2
3
3
5
6
答案 0 :(得分:5)
int x
不是const
。因此&x
会产生int*
。以下是两个候选函数:
int t<int*>(T const&)
(相当于int t<int*>(int * const&)
)&lt; - T是int*
;需要0次转换int t<int>(T const*)
(相当于int t<int>(int const*)
)&lt; - T是int
;需要从int*
转换为int const*
选择更好的匹配,即没有转换的匹配。这是参考版本。
答案 1 :(得分:2)
在这两种情况下:
cout<<t(x)<<endl;
cout<<t(&x)<<endl;
编译器正在选择template <class T> int t(const T &x)
重载,因为T
和int
分别可以满足int *
。
在这种情况下:
cout<<t2(&x)<<endl;
未选择template <class T> int t2(T &x)
重载,因为无法满足。您不能绑定对临时(rvalue)的引用,&x
是临时的。