首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板演绎和重载

模板演绎和重载
EN

Stack Overflow用户
提问于 2019-03-20 00:46:35
回答 2查看 39关注 0票数 1

这是在Primer c++ 5中的一个练习:

代码语言:javascript
复制
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);

以下是答案:

代码语言:javascript
复制
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 *)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-03-20 01:12:19

简而言之,在重载解析中包含函数模板的规则是:

  1. 名称查找确定了一组可见的函数、对象和函数模板。
  2. 集合中的每个函数模板从任何显式参数、演绎和/或默认模板参数中确定其模板参数,如果可能,这些参数将被替换以获得一个特定的具体函数签名。(如果不可能,函数模板就会被抛出集合。当模板参数推导失败时,当将参数替换为签名失败时,也就是"SFINAE“规则时,就会发生这种情况。
  3. 这些函数使用正常的重载解析规则进行比较,将来自模板的签名处理得恰如其分,就像它们是普通的非模板函数一样。
  4. 只有当步骤3认为其中两个函数不明确时,这些断带器才适用于: 如果一个函数签名来自一个模板,而另一个没有,则认为非模板函数更好。 b.如果两个函数签名都来自模板,而其中一个模板比另一个模板“更专门化”,则认为更专业的模板更好。(简单地说,“更专门化”本质上意味着我们可以向更专门化的模板证明任何有效的参数也是针对不那么专门化的模板的有效参数,但反之亦然。)

在本例的f(p)表达式中,步骤2模板#1演绎T=int*,模板2演绎T=int,因此签名如下:

代码语言:javascript
复制
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))。

票数 1
EN

Stack Overflow用户

发布于 2019-03-20 00:55:22

这不是语言律师的答案,但基本上是:

f(T)T=int*是与int*完全匹配的

f(T const*)T=int并不完全匹配int*

完全匹配就赢了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55252005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档