user1002288
user1002288

Reputation: 5040

function overloading can only be done by return value and const in C++?

Is it possible to have two versions of the same function which are the same except for return type and constness ?

I do not think so. The following example shows that. But I do not 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 double f1(int a) const cannot be counted ?

Upvotes: 3

Views: 286

Answers (4)

aroyer
aroyer

Reputation: 111

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

To my point of view, the main interest of creating member functions with the same name, but different constness in C++ is for creating const / non-const accessors on 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 reference of the member attribute m_Data. The first one returns a modifiable Data when you make a call on modifiable Foo instance. The second one returns a const Data when you make a call on a const Foo instance.

Otherwise, I would advise to avoid such design.

Yours,

Upvotes: 2

Kerrek SB
Kerrek SB

Reputation: 476980

You can't overload on return type, for obvious reasons.

You can however overload on the constness of the implicit instance argument. Compare:

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

(This example also illustrates why it makes no sense to attempt to "overload on return type": How would you make the decision in this example?)

Upvotes: 4

Skizz
Skizz

Reputation: 71060

I guess the main issue 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 it the int version and the value is promoted to a float, or is it the double version and the value is truncated?

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

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

and then the compiler can work out which one to call or generate an error if there's no matching type.

Upvotes: 4

PlexQ
PlexQ

Reputation: 3110

Not unless you declare the return type as a common super type, like void* and then cast the result back to what you need. This is of course highly evil.

You might consider wrapping the return type up in an Object which can be smart about what it contains which sort of solves the problem. This is what most OO systems end up doing pretty frequently, it's one reason why encapsulation can be so darn helpful.

it's also how generics are awesome. I'd have to check my C++ syntax, but you can declare a function whose return type is related to its argument type, or based on the generic of the subclass.

But with base-types, no, not really.

Upvotes: 1

Related Questions