Reputation: 546
Let's say I have a very simple class
class C {
private:
int _a;
int _b;
public:
C (int a, int b) :_a { a }, _b { b } {}
int a () { return _a; }
int b () { return _b; }
bool operator== (C c) {
return this->_a == c.a() && this->_b == c.b();
}
};
and I want to overload the operator +=
such that
C foo(8, 42);
C bar(1, 1);
C zoo(9, 43);
foo += bar;
assert(foo == zoo);
runs fine.
As far as I've read other people code, I should write something like
C operator+= (C c) {
return { this->_a += c.a(), this->_b += c.b() };
}
but to my understanding, return
ing something is useless. Indeed, the assertion above does not fail even when I overload +=
as
void operator+= (C c) {
this->_a += c.a();
this->_b += c.b();
}
or
C operator+= (C c) {
this->_a += c.a();
this->_b += c.b();
return C(0,0);
}
TL;DR: why shouldn't I return void when overloading +=
?
Upvotes: 2
Views: 182
Reputation:
Expected behaviour of +=
is that it evaluates as its own first operand (the x
in x += y
), as a value that can subsequently be assigned to. This is how +=
works for the built-in types, and generally speaking, custom operators should behave like the built-in operators unless you have a specific reason not to (such as operator<<
and operator>>
for I/O).
This means the implementation should look like:
C &operator+= (C c) {
this->_a += c.a();
this->_b += c.b();
return *this;
}
and it means the user can write code such as
if ((foo += bar) == zoo) { ... }
or
(foo += bar) += baz;
which are possible with the built-in types, and are sometimes (although admittedly not often) actually useful.
Your assertion says something about the side effect of operator+=
, not its result, that's why you don't notice any possible difference based on the return type.
Upvotes: 5
Reputation: 29976
Returning the left-hand side of the expression allows you to chain operators, or to use the result of the assignment in a single line, i.e.
int c = a += b;//this is so ugly :'(
or
if(a+=b)
{
}
Also, this is the behaviour that you will have on the built-in types (paragraph 13.6 of the c++ standard), so it is a good idea to mimic it for all your custom clases
Upvotes: 2