2

I try to overload the operator<<, but there is a warning that I cannot overload it. I can overload this operator as follows:

std::cout << test4 << std::endl;

But I can not overload it as follows:

std::cout << test2 + test3 << std::endl;

My main code is:

Stonewt test2(2, 8, Stonewt::STONE);
std::cout << "test2: " << test2 << std::endl;

Stonewt test3(2, 3, Stonewt::POUNDS);

std::cout << "test3: " << test3 << std::endl;

Stonewt test4 = test2 + test3;
std::cout << test4 << std::endl;         // operator << can overload
std::cout << test2 + test3 << std::endl; // operator << cannot overload

Below is the friend function

std::ostream& operator <<(std::ostream& os, Stonewt& a)
{
    if (a.format == Stonewt::STONE)
    {
        os << "stone format" << '\n';
        os << a.stone << " stones " << a.pound << " pounds" << '\n';
    }
    else if (a.format == Stonewt::POUNDS)
    {
        os << "pounds format" << '\n';
        os << a.pounds << " pounds" << '\n';
    }
    else
        os << "not valdid" << '\n';
    return os;
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
Youshikyou
  • 365
  • 1
  • 8
  • 2
    The operation `test2+test3` results in a *temporary* object, an *rvalue* which as mentioned can't be bound by non-constant references. – Some programmer dude Aug 09 '19 at 13:14
  • 2
    This error has nothing to with operator overloading, it's just about the rule saying you can't bind a non-const reference to a temporary. You would have got the same problem even if you were just writing regular functions instead of operator overloading. – john Aug 09 '19 at 13:22
  • 2
    @Slava I think even Microsoft have moved on from that issue. Now about that friendly g++ compiler that thinks `int a[n];` is OK for variable `n`. – john Aug 09 '19 at 13:24

2 Answers2

5

The test2+test3 results a temporary Stonewt object(rvalue) which can not be bound to a non-const reference(lvalue: i.e. Stonewt &a),rather with a const qualified lvalue reference. Therefore change the non-member function to:

std::ostream & operator <<(std::ostream &os, const Stonewt &a)
//                                           ^^^^^^^^^^^^^^^^
{
      // ....
      return os;
}

Further readings:

JeJo
  • 30,635
  • 6
  • 49
  • 88
0

This is not the operator<< not working for test2 + test3. It is missing an operator+.

You need to overload the operator+ so the 'test2 + test3' will work. The overload of operator<< is working but the compiler has no idea what to do when it encounters 'test2 + test3', thus issuing the assumed error.

HBatalha
  • 245
  • 4
  • 17