Why don\'t more mainstream statically typed languages support function/method overloading by return type? I can\'t think of any that do. It seems no less useful or reasona
Good answers! A.Rex's answer in particular is very detailed and instructive. As he points out, C++ does consider user-supplied type-conversion operators when compiling lhs = func();
(where func is really the name of a struct). My workaround is a bit different - not better, just different (although it's based on the same basic idea).
Whereas I had wanted to write...
template <typename T> inline T func() { abort(); return T(); }
template <> inline int func()
{ <<special code for int>> }
template <> inline double func()
{ <<special code for double>> }
.. etc, then ..
int x = func(); // ambiguous!
int x = func<int>(); // *also* ambiguous!? you're just being difficult, g++!
I ended up with a solution that uses a parameterized struct (with T = the return type):
template <typename T>
struct func
{
operator T()
{ abort(); return T(); }
};
// explicit specializations for supported types
// (any code that includes this header can add more!)
template <> inline
func<int>::operator int()
{ <<special code for int>> }
template <> inline
func<double>::operator double()
{ <<special code for double>> }
.. etc, then ..
int x = func<int>(); // this is OK!
double d = func<double>(); // also OK :)
A benefit of this solution is that any code which includes these template definitions can add more specializations for more types. Also you can do partial specializations of the struct as needed. For example, if you wanted special handling for pointer types:
template <typename T>
struct func<T*>
{
operator T*()
{ <<special handling for T*>> }
};
As a negative, you can't write int x = func();
with my solution. You have to write int x = func<int>();
. You have to explicitly say what the return type is, rather than asking the compiler to suss it out by looking at type conversion operators. I would say that "my" solution and A.Rex's both belong in a pareto-optimal front of ways to tackle this C++ dilemma :)
In such a language, how would you resolve the following:
f(g(x))
if f
had overloads void f(int)
and void f(string)
and g
had overloads int g(int)
and string g(int)
? You would need some kind of disambiguator.
I think the situations where you might need this would be better served by choosing a new name for the function.
Most static languages also now support generics, which would solve your problem. As stated before, without having parameter diffs, there is not way to know which one to call. So if you want to do this, just use generics and call it a day.
For the record, Octave allows different outcome according to return element being scalar vs array.
x = min ([1, 3, 0, 2, 0])
⇒ x = 0
[x, ix] = min ([1, 3, 0, 2, 0])
⇒ x = 0
ix = 3 (item index)
Cf also Singular Value Decomposition.
I think this is a GAP in modern C++ definition… why ?
int func();
double func();
// example 1. → defined
int i = func();
// example 2. → defined
double d = func();
// example 3. → NOT defined. error
void main()
{
func();
}
Why can a C++ compiler can not throw an error in example "3" and accept the code in example "1+2" ??
this overloading feature is not hard to manage, if you look at it in a slightly different way. consider the following,
public Integer | String f(int choice){
if(choice==1){
return new string();
}else{
return new Integer();
}}
if a language did return overloading it would allow parameter overloading, but not duplications. this would solve the problem of:
main (){
f(x)
}
because there is only one f(int choice) to choose from.