If I thought I knew something about C ++, then you cannot overload functions with the return type.
So can someone explain what is going on here?
class A { public: typedef int _foo; }; class B {}; template<class T> typename T::_foo Foo(int) { cout << "Foo(int)\n"; return typename T::_foo(); } template<class T> typename T Foo(char) { cout << "Foo(char)\n"; return typename T(); } int main() { Foo<A>(0);
There are two classes A and B. A defines typedef _foo, B does not. There are two overloads of the function template Foo, Foo (int) and Foo (char). Foo (int) returns T :: _ foo, Foo (char) returns T.
Foo (0) is then called twice. This is an exact match for Foo (int), so I would expect Foo <A> (0) to compile ok, and Foo <B> (0) not to compile, since B does not determine the type of _foo used in the template.
What actually happens is that Foo <B> (0) completely ignores Foo (int) and instead creates Foo (char). But by normal overload resolution rules, Foo (0) is clearly an exact match for Foo (int), and the only thing that makes Foo (char) more viable is the return type, which should not be considered.
To make sure this is a return value that affects overload resolution, just add this:
template<class T> void Bar(int) { typename T::_foo a; cout << "Bar(int)\n"; } template<class T> void Bar(char) { cout << "Bar(char)\n"; } Bar<A>(0);
This makes it clear that in the absence of a return value, Foo (int) is indeed the correct overload, and that if the template cannot resolve the types used from its template argument, then refusing compilation is a normal result.
source share