这是在Primer c++ 5中的一个练习:
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 *)
发布于 2019-03-20 01:12:19
简而言之,在重载解析中包含函数模板的规则是:
在本例的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*);使用标识转换(完全匹配),而来自#2的void f(const int*);使用指针转换,因此void f(int*);从#1获胜,函数模板专门化是命名的。
的确,模板#2 void f(const T*);比模板#1 void f(T);更专业。但是由于第三步决定了答案,所以我们永远不会进入第四步,所以这并不重要。(第4步使用了另一个表达式f(p2))。
发布于 2019-03-20 00:55:22
这不是语言律师的答案,但基本上是:
f(T)与T=int*是与int*完全匹配的
f(T const*)与T=int并不完全匹配int*。
完全匹配就赢了。
https://stackoverflow.com/questions/55252005
复制相似问题