1
class Fraction
{
private: 
    int numer;                                                    //fraction numerator
    int denom;                                                    //fraction denominator

public:
    Fraction(int num, int den): numer(num), denom(den) {};

    friend Fraction operator+(Fraction& frac1, Fraction& frac2);  // add fraction
    friend Fraction operator-(Fraction& frac);                    // negative fraction 
    friend Fraction operator-(Fraction& frac1, Fraction& frac2);  // subtract fraction
};


Fraction operator+(Fraction& frac1, Fraction& frac2)              // everything OK
{
    return Fraction(frac1.numer * frac2.denom + frac2.numer * frac1.denom, frac1.denom * frac2.denom);
}


Fraction operator-(Fraction& frac)                                // everything OK
{
    return Fraction(-frac.numer, frac.denom);
}


Fraction operator-(Fraction& frac1, Fraction& frac2)              // here begin some problems
{
    return frac1 + (-frac2);
}

Everything work except the last function. It don't see the variable and just give the compiler error:

Error C2679 binary '+': no operator found which takes a right-hand operand of type 'Fraction' (or there is no acceptable conversion)

What's problem?

Fenix FVE
  • 53
  • 4

2 Answers2

4

You cannot bind a non-const reference to a temporary, change your code like this

friend Fraction operator+(const Fraction& frac1, const Fraction& frac2);

Same with all the other operators.

In frac1 + (-frac2); the value of -frac2 is a temporary. It's a object created during the evaluation of the expression in a temporary location. C++ doesn't allow binding of temporaries to non-const references. Therefore always use const references for parameters when:

  1. The function does not need to modify any member variables of the object.
  2. The function does not need to call any non-const member functions of the object.
R Sahu
  • 204,454
  • 14
  • 159
  • 270
john
  • 85,011
  • 4
  • 57
  • 81
1

I disagree with john's answer. The better solution is to simply remove the reference. Pass by value makes perfect sense for a two-integer object:

inline friend Fraction operator+(Fraction frac1, Fraction frac2);

(You need the inline because the code looks like it comes from a "Fraction.h" header. Without inline you have an ODR-violation if you include Fraction.h twice.)

MSalters
  • 173,980
  • 10
  • 155
  • 350