0

Given the following code:

#include <iostream>
using namespace std;

class B {
private:
    int n;
public:
    B(int x) :
            n(x) {
    }
    B operator+(B& b) {
        return B(n + b.n);
    }
    friend ostream& operator<<(ostream &out, const B& b) {
        out << "B: " << b.n;
        return out;
    }
    bool operator<(const B& rhs) const {
        return n < rhs.n;
    }
};

int main() {
    B b1(1), b2(2), b3(3);
    const B b4 = b1 + (b2 + b3); // error
    cout << b4 << b1 << b2 << b3;
    return 0;
}

I know that if I will change this :

B operator+(B& b)

To:

B operator+(const B& b)

So it's will be ok. But, why it's really fix it?

invalid initialization of non-const reference of type 'B&' from an rvalue of type 'B'

(I understand the meaning of the error, but, I don't understand why the changing fix the error).


In addition, what is the difference between the code above (that give me error), to the following code:

class D: public B {
    double m;
public:
    D() :
            B(0), m(0) {
    }
    D(int x, int y) :
            B(x), m(y) {
    }
    D operator+(D& d) { // ~~
        return d;
    }
    friend ostream& operator<<(ostream &out, const D& d) {
        out << static_cast<const B&>(d);
        out << ", D: " << d.m;
        return out;
    }
};

int main() {
    B b4(4);
    D d1(1, 0), d2(1, 2);
    D d3 = d1 + d2;
    cout << b4 << ", " << d3 << endl;
    return 0;
}

Why now I don't get at ~~ also error?

Software_t
  • 576
  • 1
  • 4
  • 13
  • 1
    I suggest you start by learning the different [value categories](https://en.cppreference.com/w/cpp/language/value_category) in C++. – Some programmer dude Jul 09 '18 at 13:13
  • Because `operator+()` returns a value, and accepts arguments by non-`const` reference. The result of `(b1 + b2)` cannot be bound to a non-`const` reference, but is being passed by non-`const` reference in order to add it to `b1`. Simple fix for the error: change `B operator+(B &b)` to `B operator+(const B &b) const`. – Peter Jul 09 '18 at 13:20
  • The `const` will ensure that the lifetime of the value referenced [is extended](https://stackoverflow.com/q/2784262/1460794). – wally Jul 09 '18 at 13:20
  • 1
    Related : [Can't pass temporary object as reference](https://stackoverflow.com/questions/27463785/cant-pass-temporary-object-as-reference) – François Andrieux Jul 09 '18 at 13:23
  • 2
    Possible duplicate of [Can't pass temporary object as reference](https://stackoverflow.com/questions/27463785/cant-pass-temporary-object-as-reference) – Caleth Jul 09 '18 at 13:23
  • @Someprogrammerdude Can you see my edit to the question? what is the difference between the examples? – Software_t Jul 09 '18 at 13:35
  • Because now when you do `d1 + d2` you don't have any *rvalues*. If you add a fourth object `d4` and do `d1 + d2 + d4` (like you did before) you would still get an error. – Some programmer dude Jul 09 '18 at 13:39
  • @Someprogrammerdude but d1 and d2 are not a temporary ? – Software_t Jul 09 '18 at 14:24
  • No, but the *result* of `d1 + d2` is a temporary object and an rvalue. – Some programmer dude Jul 09 '18 at 15:02

0 Answers0