c++operator-overloadingcode-reuse

C++ - why implement op+ in terms of op+= and not the other way around?


Why is this implementation:

T& T::operator+=(const T&) {
  // ... implementation ...
  return *this;
}

T operator+(const T& lhs, const T& rhs) {
  T temp(lhs);
  return temp += rhs;
}

more common than this one:

T& T::operator+=(const T& rhs) {
  *this = *this + rhs;
  return *this;
}

T operator+(const T& lhs, const T& rhs) {
  // ... implementation ...
  return some_result;
}

Is there any reason at all, or is it just a random coincidence that I've seen people implement it this way multiple times in the literature that I read, and never the other way around?


Solution

  • operator+ has to create a new object to hold the result. operator+= doesn't need a new object.

    If you write operator+= in terms of operator+, then you end up paying for an extra new object creation, an assignment (or swap), and a destruction, all of which you didn't need.

    Besides that, on many processors, the hardware has direct support for += and similar operations where the result is stored back to one of the input registers, and none for storing to a third register (like +).

    BTW, there's a mistake in your (original, now edited) code that hides part of the extra work. You actually need:

    T& T::operator+=( const T& rhs )
    {
        *this = *this + rhs; // creation of temporary, move assignment, and destruction of temporary
        return *this;
    }
    

    Even worse, your (again original, now edited) suggested implementation of operator+ fails to return the new object properly, it returns a dangling reference instead. That's undefined behavior.


    For those interested, the first operator+ implementation can be improved even further by using pass-by-value:

    T operator+( T lhs, const T& rhs )
    {
        lhs += rhs;
        return lhs;
    }
    

    Now if the left hand operand of operator+ is a temporary, the move constructor will be used, avoiding a copy. Although with NRVO, there probably isn't much advantage in the resulting code either way.