这是Primer c ++ 5th中的练习:
template <typename T> void f(T); //1
template <typename T> void f(const T*); //2
template <typename T> void g(T); //3
template <typename T> void g(T*); //4
int i = 42, *p = &i;
const int ci = 0, *p2 = &ci;
g(42); g(p); g(ci); g(p2);
f(42); f(p); f(ci); f(p2);
这是答案:
g(42); //type: int(rvalue) call template 3 T: int instantiation: void g(int)
g(p); //type: int * call template 4 T: int instantiation: void g(int *)
g(ci); //type: const int call template 3 T: const int instantiation: void g(const int)
g(p2); //type: const int * call template 4 T: const int instantiation: void g(const int *)
f(42); //type: int(rvalue) call template 1 T: int instantiation: void f(int)
f(p); //type: int * call template 1 T: int * instantiation: void f(int *)
f(ci); //type: const int call template 1 T: const int instantiation: void f(const int)
f(p2); //type: const int * call template 2 T:int instantiation: void f(const int *)
我的问题是为什么f(p)
赞成f(T)
而不是f(const T *)
的实例化
简而言之,在重载解析中包含函数模板的规则是:
在此示例的f(p)
表达式中,在步骤2中,模板#1推导出T=int*
,模板#2推导出T=int
,因此签名为:
void f(int*); // from 1
void f(const int*); // from 2
在第3步中,参数p
的类型为int*
,因此来自#1的void f(int*);
使用Identity转换(精确匹配),而来自#2的void f(const int*);
使用指针转换,因此来自#1的void f(int*);
获胜,并且该函数模板专门化是一个名字。
模板#2 void f(const T*);
比模板#1 void f(T);
更专业。但是,由于第3步确定了答案,我们从未进入第4步,所以这并不重要。 (步骤4的确用于另一个表达式f(p2)
。)