此代码段无法在MSVC,Clang和Gcc中编译(它们给出不同的错误消息):
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;
}
这不是应该编译吗?我看不到为什么它无法解析重载函数或推导模板参数。欢迎任何帮助,谢谢。
PS:如果模板被void foo(int (*)(int, int))
替换,或者为避免过载而重命名foo
之一,它将编译。
答案 0 :(得分:10)
为简单起见,我们将第一个重载称为foo1
,然后将第二个重载称为foo2
。
对于模板,问题在于无法根据[temp.deduct.call]/6推论外部foo
的模板参数:
如果参数是包含一个或多个函数的重载集 模板,则将参数视为非推导上下文。
在没有模板的情况下,该程序会考虑foo1(foo1)
,foo1(foo2)
,foo2(foo1)
,foo2(foo2)
的所有可能性,并根据{{ 3}}:
[注意::如果
foo2(foo1)
和f()
都是重载函数,则叉号 必须考虑可能性的乘积来解决g()
,或者 等价表达式f(&g)
。 — 尾注]