1
votes

Why the following code doesn't compile:

B b1(1), b2(2), b3(3);
const B b4 = b1 + (b2 + b3);

Until I replace this:

B operator+(B& b) {
    return B(n + b.n);
}

with this:(I don't know why to write const the compiler suggested that)

B operator+(const B& b) {
    return B(n + b.n);
}

Errors I get:

invalid operands to binary expression ('B' and 'B')

note: candidate function not viable: expects an l-value for 1st argument

note: candidate template ignored: could not match 'reverse_iterator' against 'B' operator+(typename reverse_iterator<_Iter>::difference_type __n, const reverse_iterator<_Iter>& __x)

Plus, why this works? (it's similar to the previous case)

bool Test(int x)
{
    return x==0;
}
Test(0);
1
Temporaries cannot bind to non-const l-value reference. - Jarod42
BTW, you still miss a const: B operator+(const B& b) const. - Jarod42
b1 and the rest are not temporaries @Jarod42 - user13737139
It works without the other const - user13737139
Plus why changing the parameter (and not returning value) as const solves this? may someone post full answer, that doesn't make sense - user13737139

1 Answers

1
votes
const B b4 = b1 + (b2 + b3);

According to the order of operations, the first subexpression to evaluate is b2 + b3. This invokes B::operator+, which returns a B object. More precisely, a temporary B object is returned, one that will be used to help evaluate this full expressions and then discarded. This is much like making notes on scratch paper as you work through a long calculation by hand.

The next subexpression to evaluate is b1 plus the temporary object. This invokes b1.operator+ with the temporary B object as the argument. When the operator's signature is

B operator+(B& b)

there is a problem because the C++ language states that a non-const reference cannot bind to a temporary object. That is, the reference parameter (B& b) does not match the temporary object. You can solve this by changing the reference from one that is not const-qualified to one that is.

B operator+(const B& b)

This version of the operator takes a const reference, which can bind to a temporary object. (Again, this is simply a rule of the language. You can debate the reasons for it, but the rule still stands.)

Note that this is not a full solution since addition tends to be symmetric. To accommodate the scenario where the left side of the parentheses is const-qualified, *this also needs to be const-qualified.

B operator+(const B& b) const

For more tips, see the basic rules and idioms for operator overloading. You might find that you don't necessarily want operator+ to be a member function.