当前位置: 首页 > 知识库问答 >
问题:

用auto解决模板函数的重载问题

羊舌子瑜
2023-03-14

具有以下3种重载

template <class T> auto foo() { return 1; }
template <class T> int  foo() { return 2; }
template <class T> T    foo() { return 3; }

以下内容是否格式不正确?

static_cast<int(*)()>(&foo<int>)();

Clang选择重载#2,而gcc无法编译(演示)

移除过载#1时,双方同意选择过载#2(演示)。

删除重载#2时,gcc选择重载#1,clang编译失败(演示)

共有1个答案

樊胜
2023-03-14

根据[over.over]/2,我们执行模板参数推导。这将在所有三个重载中成功:在第一个重载中,请记住[temp.decrete.funcaddr]/2:

函数模板返回类型中的占位符类型 (7.1.7.4) 是非演绎上下文。如果此类函数的模板参数推导成功,则通过函数体的实例化确定返回类型。

由于推导将成功(假设所有模板参数都显式提供了参数),因此返回类型被推导为int。在第二种情况下,由于提供了参数,推导成功,在第三种情况下,将推导出T

继续第4段,

如果选择了多个函数,[...]任何给定的函数模板特化F1被消除,如果该集合包含第二个函数模板特化,其函数模板比F1的函数模板更专业根据14.5.6.2的部分排序规则。在这样的消除之后,如果有的话,应该只保留一个选定的函数。

根据[temp.deduct.partial]/3,函数模板的函数类型用于部分排序。我们可以立即看到#1和#2的函数类型不包含任何参与演绎的模板参数,因此通过由核心问题1391的解决方案引入的对[temp.deduct.partial]/4的添加,它们对应的< code>P不用于确定排序。@bogdan在这里解释了为什么那个分辨率有问题;底线是排序只会产生#1和#2的歧义。

也就是说,根据目前(可能有缺陷的)措辞,转换在所有情况下都是病态的。如果非依赖/推导参数对的偏序是固定的,

  • 案例1和3是不明确的,因为对于两种非依赖函数类型(#1和#2),没有排序对。
  • 案例2中的接受行为是正确的(正如预期的那样)。

[temp.decrete.type]/8元素9(T()),以防您好奇。

 类似资料:
  • 模板函数与重载是密切相关的。从函数模板产生的相关函数都是同名的,因此编译器用重载的解决方法调用相应函数。 函数模板本身可以用多种方式重载。我们可以提供其他函数模板,指定不同参数的相同函数名。例如,图12.2的printArray函数模板可以用另一printArray函数模板重载,用参数lowSubscriPt和highSubscript指定要打印的数组部分(见练习12.4)。 函数模板也可以用其他

  • 编译器输出: 18:4:错误:重新定义'模板T随机::get(T, T)'12:4:注意:'模板T随机::get(T, T)'之前在这里声明在函数'int main()': 28:44:错误:没有匹配函数调用'get(浮动,浮动)'28:44:注意:候选是: 12:4:注意:模板T随机::get(T, T)12:4:注意:模板参数推导/替换失败: 这项工作很好: 还有这个: 为什么编译器无法在第一

  • Second.CPP 我在表示错误:不允许类型名。那么这个错误的原因是什么呢?我想我还没有完全了解模板的整个机制--我对这个主题非常陌生。

  • 从派生,并使用自定义结构对其进行专门化。也重载。然而,这才是问题的根源。如果我尝试编译它,我会得到: 显然,没有运算符“+”。但这是我的困惑…编译器被要求实现,因为这是继承的内容。但是,我从不使用或调用。那么编译器应该尝试生成这个基类函数吗?

  • 我试图重写模板类http://docs.ros.org/hydro/api/rviz/html/c/message__filter__display_8h_source.html使用多种消息类型,使用变量模板。 我的第一个问题是如何使用可变模板重写下面的示例代码,以便它可以用于任意数量的模板参数,而不仅仅是2个。 我需要在家长类: 每个模板类型的虚拟成员函数 每个模板类型的每个的成员函数 每个模板

  • 本文向大家介绍深入解析WordPress中加载模板的get_template_part函数,包括了深入解析WordPress中加载模板的get_template_part函数的使用技巧和注意事项,需要的朋友参考一下 最近研究官方主题 Twenty Eleven ,有一些东西网上现成的中文资料不好找,在博客里记载下来,算是分享,也算是备忘,wordpress 3.0 以后就开始便有了get_temp