Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
}
like image 943
grefab Avatar asked Jul 14 '09 22:07

grefab


3 Answers

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.

like image 88
mmx Avatar answered Oct 23 '22 10:10

mmx


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.

like image 30
EFraim Avatar answered Oct 23 '22 10:10

EFraim


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"; }
};
like image 34
AProgrammer Avatar answered Oct 23 '22 08:10

AProgrammer