Function overloading can only be done with return value and const in C ++?

Is it possible to have two versions of the same function that are the same other than return type and constant?

I do not think so. The following example shows this. But I don't know the reason.

#include<iostream>
using namespace std;
class A
{
 private:
       int bb ;
 public:
       double f1(int a) const {cout << "double f1 is called " << endl; return 0.0; }
       int f1(int a) {cout << "int f1 is called " << endl ; return 0; }

};

int main()
{
     int b = 6;
     A aa;

     double c= aa.f1(b);
     return 0 ;
}

      

output:

int f1 is called

Why can't double f1 (int a) const be counted?

+3


source to share


4 answers


For obvious reasons, you cannot overload the return type.

However, you can overload the implicit instance argument constant. For comparison:



aa.f1(b);
static_cast<A const &>(aa).f1(b);

      

(This example also shows why there is no point in trying to "overload the return type": how would you go about solving this example?)

+4


source


I think the main problem is that it easily introduces ambiguity. For example:

int main()
{
  int b = 6;
  A aa;

  float c= aa.f1(b); // which version of f1 is called here?
  return 0 ;
}

      

Is this the int version and the value is assigned to the float, or is it the double version and the value is truncated?



A possible solution is to move the return value into a pivot parameter:

void f1(int a, double &out);
void f1(int a, int &out);

      

and then the compiler can decide which one to throw or throw an error if there is no matching type.

+4


source


I agree with Skizz, the ambiguity is not safe here. In the example you give, we never know which methods of these two will be called at last (even wondering if it might depend on the compiler?).

From my point of view, the main interest for creating member functions with the same name, but with a different constant in C ++, is in creating constant / non-const accessors on the member data.

Example:

class Foo {
    private: Data m_Data;

    public: Data& getData(void) { return m_Data; }
    public: const Data& getData(void) const { return m_Data; }
};

      

Both accessors getData () retrieve the member attribute reference m_Data. The first one returns volatile data when you make a call to the modified Foo instance. The second returns const data when you call a const Foo instance.

Otherwise, I would suggest avoiding such a construction.

Your

+2


source


Not unless you declare the return type as a normal super-type like void * and then cast the result back to what you want. This is, of course, very wicked.

You might consider moving the type of the returned object to an object that might be smart about what it contains, which solves the problem. This is what most OO systems end up doing quite often, and this is one of the reasons why encapsulation can be so useful.

this is also how generics are amazing. I have to check my C ++ syntax, but you can declare a function whose return type is related to its argument type, or based on a generic subclass.

But with basic types, no, not really.

+1


source







All Articles