提问者:小点点

取地址上下文中最专业的功能模板是哪个?


考虑这个例子

#include <iostream>
template<class T>
void fun(T&){  //#1
    std::cout<<"selected\n";
}

template<class T>
void fun(T&&){}  //#2

int main() {
    void(*ptr)(int&) = &fun;  //#3
}

GCC和Clang都报告了一个错误,诊断结果“不明确”。根据[temp. dept.funcaddr#1],这样两个函数模板在#3中都是可行的。因此,[over.over#5]需要在这里应用

如果集合包含第二个函数模板专门化,其函数模板比F1的函数模板更专门,则根据[temp. func.order]的部分排序规则消除任何给定的函数模板专门化F1。

要判断#1#2之间哪个更专业,[temt. dept.部分#3.3]适用于它们

用于确定排序的类型取决于完成部分排序的上下文:

  • […]
  • 在其他上下文中使用函数模板的函数类型。

因此,用于参与部分排序的P和A应该分别是这两个函数模板的函数类型。将#2的函数类型作为P,将#1的函数类型作为A。根据[temt. dept.type#10],从A中推断出P是成功的

如果P和A是在获取函数模板的地址([temt. det.funaddr])或从函数声明([temt.det.decl])中推导模板参数时源自推导的函数类型,并且Pi和Ai分别是P和A的顶级参数类型列表的参数,如果Pi是转发引用([temp.deduct.call])并且Ai是左值引用,则Pi的类型被调整为模板参数类型(即T

相反,由于我们无法推导T


共1个答案

匿名用户

根据您自己的分析,GCC和Clang在过载分辨率中的屈服和歧义是错误的。

这可以说是与CWG 1164有关,尽管不是在函数调用的上下文中,但其意图应该可以说是类似于CWG 1164[强调我的]的函数调用的情况:

科:13.10.3.2[temp.deduct.call]状态:C 11提交者:US日期:2010-08-03

[在2010年11月会议上被选入WP。]

N3092注释US77以下示例含糊不清:

template<typename T> int f(T&);
template<typename T> int f(T&&);
int i;
int j = f(i);

由于传递给右值参数的左值的特殊演绎规则,演绎产生f(int

因为f(T

拟议决议(2010年8月):[…]

您自己的分析得到了与CWG 1164一致的重载结果,但对于另一个上下文,这在CWG 1164中从未取消,并且(可以说)不太常见。

我们可以注意到,GCC和Clangs都将CWG 1164的分辨率标记为/未知
-GCC:GCC中的C缺陷报告支持
-Clang中的C缺陷报告支持
所以它可能只被部分实现了(OP的示例比CWG 1164的示例更像是一个角落用例)。