It is well known that ordinary functions that differ only in their return type cannot be overloaded in C++.
But this limitation does not hold for overloaded function templates, for example:
int f(auto) { return 1; }
auto f(auto) { return 2; }
All compilers accept it, demo: https://gcc.godbolt.org/z/qj73Mzehd
Why does the language make such exception for the templates?
If the return type of the overloaded functions differ, then it will be possible to select one of the functions using the cast to expected function type. Surprisingly, Clang allows one to resolve the ambiguity even if the return type is actually the same, for example:
((int(*)(int))f)(3);
selects
int f(auto) { return 1; }
Demo: https://gcc.godbolt.org/z/snfvbq1ME
Is Clang wrong here?
No, you cannot overload a method based on different return type but same argument type and number in java.
Function overloading and return type in C++You cannot overload function declarations that differ only by return type. The function overloading is basically the compile time polymorphism. It checks the function signature.
Templates (normally) require that you use identical syntax to carry out the operations on all (supported) types. Function overloading is (or should be) used similarly, but allows you to use different syntax to carry out the operations for different types.
Template Function Overloading:The name of the function templates are the same but called with different arguments is known as function template overloading. If the function template is with the ordinary template, the name of the function remains the same but the number of parameters differs.
However, functions can not be overloaded if they differ only in the return type. Why is Function overloading not possible with different return types? Function overloading comes under the compile-time polymorphism. During compilation, the function signature is checked. So, functions can be overloaded, if the signatures are not the same.
Function overloading is possible in C++ and Java but only if the functions must differ from each other by the types and the number of arguments in the argument list. However, functions can not be overloaded if they differ only in the return type. Why is Function overloading not possible with different return types?
For reference, our extensible and checkable version of return-type overloading in C++: Anyone can register new types, optionally using SFINAE to conditionally support them: has_from_string<T> can be used to test (at compile time) if a from_string is available for a certain type:
………. …… ….. ……. where, T is template argument accepting different arguments and class is a keyword. The name of the function templates are the same but called with different arguments is known as function template overloading.
Why does the language make such exception for the templates?
You mean this?
signature [defns.signature.templ]
⟨function template⟩ name, parameter-type-list, enclosing namespace (if any), return type, template-head, and trailing requires-clause (if any)
Yes, the return type is there. It's what always made possible things like
template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type foo(T&);
template<typename T>
typename std::enable_if<!std::is_integral<T>::value>::type foo(T&);
SFINAE is why the return type is included in the signature. Substitution failure is possible in the return type, so it's part of signature comparison. You can still potentially generate two conflicting specializations to overload on (in the general case, not in the example), but the templates would be different.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With