Why do implicit conversion member functions overloading work by return type, while it is not allowed for normal functions?

StackOverflow https://stackoverflow.com/questions/1128501

Question

C++ does not allow polymorphism for methods based on their return type. However, when overloading an implicit conversion member function this seems possible.

Does anyone know why? I thought operators are handled like methods internally.

Edit: Here's an example:

struct func {
    operator string() { return "1";}
    operator int() { return 2; }
};

int main( ) {
    int x    = func(); // calls int version
    string y = func(); // calls string version
    double d = func(); // calls int version
    cout << func() << endl; // calls int version
}
Was it helpful?

Solution

Conversion operators are not really considered different overloads and they are not called based on their return type. The compiler will only use them when it has to (when the type is incompatible and should be converted) or when explicitly asked to use one of them with a cast operator.

Semantically, what your code is doing is to declare several different type conversion operators and not overloads of a single operator.

OTHER TIPS

That's not return type. That's type conversion.

Consider: func() creates an object of type func. There is no ambiguity as to what method (constructor) will be invoked.

The only question which remains is if it is possible to cast it to the desired types. You provided the compiler with appropriate conversion, so it is happy.

There isn't really a technical reason to prevent overloading of functions on the result types. This is done in some languages like Ada for instance, but in the context of C++ which has also implicit conversions (and two kind of them), the utility is reduced, and the interactions of both features would quickly leads to ambiguities.

Note that you can use the fact that implicit conversions are user definable to simulate overloading on result type:

class CallFProxy;
CallFProxy f(int);

class CallFProxy {
   int myParameter;
   CallFProxy(int i) : myParameter(i) {}
public:
   operator double() { std::cout << "Calling f(int)->double\n"; return myParameter; }
   operator string() { std::cout << "Calling f(int)->string\n"; return "dummy"; }
};

Overload resolution chooses between multiple candidate functions. In this process, the return type of candidates is indeed not considered. However, in the case of conversion operators the "return type" is critically important in determining whether that operator is a candidate at all.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top