Overloading by Return Type

Overloading by return type

No there isn't. You can't overload methods based on return type.

Overload resolution takes into account the function signature. A function signature is made up of:

  • function name
  • cv-qualifiers
  • parameter types

And here's the quote:

1.3.11 signature

the information about a function that participates in overload
resolution (13.3): its parameter-type-list (8.3.5) and, if the
function is a class member, the cv-qualifiers (if any) on the function
itself and the class in which the member function is declared. [...]

Options:

1) change the method name:

class My {
public:
int getInt(int);
char getChar(int);
};

2) out parameter:

class My {
public:
void get(int, int&);
void get(int, char&);
}

3) templates... overkill in this case.

Typescript: ReturnType of overloaded function

As Matt McCutchen points this is a limitation of ReturnType and in general conditional types and multiple overload signatures.

We can however construct a type that will return all overloaded return types for up to an arbitrary number of overloads:

function applyChanges1(input: string): number
function applyChanges1(input: number): string
function applyChanges1(input: number | string): number | string {
return typeof input === "number" ? input.toString() : input.length
}

function applyChanges2(input: number): string
function applyChanges2(input: string): number
function applyChanges2(input: number | string): number | string {
return typeof input === "number" ? input.toString() : input.length
}


type OverloadedReturnType<T> =
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R; (...args: any[]) : infer R ; (...args: any[]) : infer R } ? R :
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R; (...args: any[]) : infer R } ? R :
T extends { (...args: any[]) : infer R; (...args: any[]) : infer R } ? R :
T extends (...args: any[]) => infer R ? R : any


type RetO1 = OverloadedReturnType<typeof applyChanges1> // string | number
type RetO2 = OverloadedReturnType<typeof applyChanges2> // number | string

The version above will work for up to 4 overload signatures (whatever they may be) but can easily (if not prettily) be extended to more.

We can even get a union of possible argument types in the same way:

type OverloadedArguments<T> = 
T extends { (...args: infer A1) : any; (...args: infer A2) : any; (...args: infer A3) : any ; (...args: infer A4) : any } ? A1|A2|A3|A4 :
T extends { (...args: infer A1) : any; (...args: infer A2) : any; (...args: infer A3) : any } ? A1|A2|A3 :
T extends { (...args: infer A1) : any; (...args: infer A2) : any } ? A1|A2 :
T extends (...args: infer A) => any ? A : any


type RetO1 = OverloadedArguments<typeof applyChanges1> // [string] & [number]
type RetO2 = OverloadedArguments<typeof applyChanges2> // [number] & [string]

Overload with different return type in Java?

You can't do it in Java, and you can't do it in C++. The rationale is that the return value alone is not sufficient for the compiler to figure out which function to call:

public int foo() {...}
public float foo() {..}

...
foo(); // which one?

Function overloading with different return types

How will I make the convert() work if I want it to have it different return types by overloading the function ?

You can create a simple function template.

template <typename T>
T convert(std::string const& num){
std::istringstream ss(num);
T d_num;
ss>>d_num;
return d_num;
}

and specialize it for std::string so that the input argument is used to copy construct the returned std::string.

template <>
std::string convert<std::string>(std::string const& in){
return in;
}

and use it as:

auto d1 = convert<double>(st);
auto i1 = convert<int>(st);

Function return type overloading C++

You cannot overload based on return type alone. In a nutshell, the compiler figures out what overload to call based on the arguments. Hence, you cannot distinguish two overloads based only on return type:

int f() { return 42; }
double f() { return 3.14; } // error redeclaration of f()

f(); // calls what function ?!?

When parameter types differ, two overloads can have different return types:

 int g() { return 42; }          // (1)
double g(int) { return 3.14; } // (2)

g(); // calls (1)
g(1); // calls (2)

While vanilla overloading does not let you overload based only on the return type, there is a neat trick that can emulate it. Bear with me.

The above f overloads cause a compiler error, because they arent a valid overload set (differ only by return type). But we can define two seperate functions:

int f_int(){ return 42; }    
double f_double() { return 3.14; }

We can define a type whose purpose is nothing but to be convertible to either an int or a double. During that conversion we can call the respective f_x:

struct foo {
operator int() { return f_int(); }
operator double() { return f_double(); }
};

Now these two lines:

int x = foo{};
double y = foo{};

call f_int or f_double, respectively, based on what we assign it too.

live demo

However, take this with a grain of salt. It is rare that you actually need to overload based on return type only. Those two lines can be rather obscure when it isnt clear from context what is happening. Implicit conversions are always a source of confusion. Last but least, it also doesn't go well with "almost always auto".

Overloading function with different return type

The compiler has no way of knowing what you're calling. I suggest making the names more descriptive like so:

public static Point3d[] GetNGonCenters3D(this Mesh mesh)

And

public static Point3f[] GetNGonCenters3F(this Mesh mesh)

Overloading will not work here as they're both using the same parameters, the compiler can't guess what return type you want.

Method Overloading with different return type

The C# specification (section 10.6) states that overloaded members may not differ by only return type and as per http://msdn.microsoft.com/en-us/library/ms229029.aspx

As per your question regarding creating parameters simply to support differing return types? I personally believe that is a terrible solution to the problem. Code maintenance will become difficult and unused parameters are a definite code smell. Does the method really need to be overloaded in that case? Or does it belong in that class? Should something else be created to convert from one return type to another? All things you should ask to derive a more idiomatic solution.



Related Topics



Leave a reply



Submit