I looked a few related stack overflow threads such as This case of template function overloading eludes my understanding
and
Function overloading by return type?
but neither seem to give me precisely the answer I'm looking for, at least not in a way that has been easy for me to interpret.
My question boils down to this: why, from both a design and technical standpoint, is it legal to do this:
#include <iostream>
using namespace std;
template<class T>
void func(){
cout << "Compiler inferred from void return value!\n";
}
template<class T>
int func(){
cout << "Compiler inferred from int return value!\n";
return 0;
}
int main(){
void (*thisFunc)()=func<int>;
int (*thatFunc)()=func<int>;
thisFunc();
thatFunc();
}
But not this:
#include <iostream>
using namespace std;
void func(){
cout << "You won't see this because it won't compile!\n";
}
int func(){
cout << "Nor this one!\n";
return 0;
}
int main(){
void (*thisFunc)()=func;
int (*thatFunc)()=func;
thisFunc();
thatFunc();
}
It is worth mentioning that the first example won't compile if I do not explicitly give func an arbitrary template parameter when initializing thisFunc and thatFunc. The only other difference between the two is that the first one has func templated by a type which is completely immaterial, except that it is apparently allowing me to overload by return type. The compiler is even able to make an inference in that case on which function to call, making the illegality of function overloading by return type in c++ somewhat baffling to me. In any case, it's a neat trick I guess.
EDIT: The thing that bothers me the most is the inconsistency: I would think very long and hard before I genuinely considered overloading by return type, but if the "fix" for someone who wants to overload by return type is to simply add a meaningless template parameter or apparently wrap the functions inside namespaces, then I would think either C++ should either more or less strict about what it considers ambiguous. Is there a compelling reason why templates and namespaces need this functionality to work correctly? Is there an example of desirable code that could not work if, for instance, templates were not allowed to disambiguate code as in my example? I am asking from a language design standpoint, not a compiler compliance standpoint.