Giuseppe Crinò
Giuseppe Crinò

Reputation: 546

Why overloading of += never return nothing in other people's code?

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, returning 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

Answers (2)

user743382
user743382

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

SingerOfTheFall
SingerOfTheFall

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

Related Questions