为什么此模板参数推导/重载解析失败?

fel*_*lix 7 c++ templates language-lawyer overload-resolution

此代码段无法在MSVC,ClangGcc中编译(它们提供不同的错误消息):

int foo(int a, int b) {
    return a + b;
}

template <class Ret, class A, class B>
void foo(Ret (*)(A, B)) {

}

int main() {
    foo(foo);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这不应该编译吗?我无法理解为什么它无法解析重载函数或推断模板参数.欢迎任何帮助,谢谢.

PS:如果替换模板void foo(int (*)(int, int)),或者我们重命名模板foo以避免超载,则编译它.

xsk*_*xzr 10

为简单起见,让我们调用第一个重载foo1并调用第二个重载foo2.

使用模板,问题是你不能foo根据[temp.deduct.call]/6推断出外部的模板参数:

如果参数是包含一个或多个函数模板的重载集,则该参数将被视为非推导的上下文.

无模板,所述程序考虑所有可能性foo1(foo1),foo1(foo2),foo2(foo1),foo2(foo2)并选择是唯一可行的foo2(foo1),根据[over.over]/6:

[  注意:如果f()g()都是重载函数,则必须考虑解决可能性的交叉乘积f(&g)或等效表达式f(g).-  结束说明  ]

  • 也许添加一个非推断的上下文意味着模板[不被认为](https://timsong-cpp.github.io/cppwp/over.over#2)为外部`foo()` (4认同)