简体   繁体   中英

Why does this template argument deduction/overload resolution fail?

This code snippet fails to compile in MSVC , Clang and Gcc , (they give different error message):

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;
}

Shouldn't this compile? I can't see why it fails in resolving the overloaded function or in deducing the template arguments. Any help is welcome, thanks.

PS: It compiles if the template is replaced with void foo(int (*)(int, int)) , or if we rename one of foo to avoid overloading.

For simplicity, let's call the first overload foo1 and call the second overload foo2 .

With templates, the problem is that you cannot deduce the template arguments for the outer foo , according to [temp.deduct.call]/6 :

If the argument is an overload set containing one or more function templates, the parameter is treated as a non-deduced context.

Without templates, the program considers all possibilities foo1(foo1) , foo1(foo2) , foo2(foo1) , foo2(foo2) and chooses the only viable one foo2(foo1) , according to [over.over]/6 :

[ Note: If f() and g() are both overloaded functions, the cross product of possibilities must be considered to resolve f(&g) , or the equivalent expression f(g) . end note ]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM