abc
abc

Reputation: 526

Operator overloading - does not match

I'm have a bit problem with operator overloading. I have two classes.

#include <iostream>
using namespace std;

    class Meter; //Forward declaration        

    class Inch{
    private:
        double inches;

    public:
        Inch() : inches(0) {}
        Inch(double i) { inches=i; }
        friend Inch operator+ (const Meter& m, const Inch& i);
        void out(){ cout << "Inch:" << inches << "\n";  }
        double getInches() const { return inches; }
    };

and

class Meter{
private:
    double meter;    
public:
    Meter() : meter(0) {}
    Meter(double m) { meter=m; }
    Meter operator+ (const Inch& i) { return Meter(meter + i.getInches() * 0.0254); }    
    void out(){ cout << "Meter:" << meter;  }
    double getMeter() const { return meter; }
};

Inch operator+ (const Meter& m, const Inch& i)
{ return Inch(m.getMeter()/0.0254 + i.getInches()); }

In main I have one of each of these classes. I need to add them together with the order : m + i; So m must be the first object. In order to do that, I used friend function in order to use two objects as a parameter.

Inch i(6.4), resultInch; 
Meter m(14), resultMeter; 

i.out(); 
m.out();  

resultMeter = m + i; 
resultMeter.out(); 

resultInch = m + i; 
resultInch.out();

With the above, resultMeter holds the correct value, but when I put resultInch compiler gives the "error no match for bla bla bla".

What am I missing?

Upvotes: 0

Views: 231

Answers (4)

Tomek
Tomek

Reputation: 4659

Remove operator+ from both classes. Create proxy class which will be used as the result of addition:

class ProxyMeterInch
{
  private:
    double op1, op2;
  public:
    friend ProxyMeterInch operator+(Meter m, Inch i)
    {
      ProxyMeterInch r;
      r.op1 = m.getMeter();
      r.op2 = i.getInch() * 0.0254; // I tend to keep it in meters as I am European
      return(r);
    }
    operator Meter() const
    {
      return(op1 + op2);
    }
    operator Inch() const
    {
      return((op1 + op2) / 0.0254);
    }
};

You get the idea. Depending on the type you are trying to assign to correct conversion operator will be selected.

Upvotes: 1

John
John

Reputation: 7339

C++ cannot overload on return value. So when you want to be able to say:

meters = meters + inches;

and

inches = meters + inches;

both meters + inches are the same function. I second the recommendation to write one length class with a units attribute and conversion functions. But lacking that, I recommend you write conversion operators between your two length classes. Then only one addition function is needed (you should still write two: meters + meters and inches + inches) and the types can be converted back and forth.

Upvotes: 3

Pawel Zubrycki
Pawel Zubrycki

Reputation: 2713

Ok, so I assume it's

Inch resultInch = m + i; // not Meter resultInch (...)

It is equivalent to:

Inch resultInch = (Meter)m.operator+(i);

and you have no way of converting between Meter and Inch.

Try changing it to Inch resultInch = i + m;.

Upvotes: 0

The problem is that both these two operators are overloads for the exact same + in code. You can either use one or another, but not both in the same program.

Inch operator+ (const Meter& m, const Inch& i);
class Meter{
   Meter operator+ (const Inch& i);
};

Consider what would happen if you had one Meter m; and Inch i; and you try to add them with m + i, which operator implementation should be called?

Upvotes: 7

Related Questions