Search code examples
c++operator-overloading

C++ binary arithmetic operator overloading


I read the cppreference page for operator overloading - "binary arithmetic operators". I was confused by a comment in a piece of code, which encouraged passing by value, instead of reference, for compiler optimisation. I'm not experienced so I might've missed some information, but to my knowledge, passing by reference is encouraged over passing by value when possible.

First example:

class A {
   public:
   A& operator+=(A const& rhs) {
      /*...*/
      return *this;
   }

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

In this code, it is stated that passing lhs by value in operator+ helps to optimise chained addition. This, to my understanding, stands in contrast to this answer on SO, which states that passing by value prevents "named return value optimisation".

Second example:

inline A operator+(A const& lhs, X const& rhs) {
  A a = lhs;
  a += rhs;
  return a;
}

The second example provides A a = lhs;, which, explained by the accepted answer to this thread, states that the optimisation of the first example is true if operator+ is implemented in terms of operator+=.

Is the optimisation of the first example true if operator+ is implemented without operator+=?

Which of these implementations are preferred for computational efficiency, provided that the second example includes "named return value optimisation" ?

Is there any other reason to prefer one over the other?


Solution

  • The essence of this advice is to generally prefer passing a function parameter by value instead of copying inside the function. The reason is that passing by value involves copying only if the actual argument is lvalue, otherwise it involves moving. Consider:

    Matrix a, b, c;
    //...
    Matrix d = a + b + c;
    

    Here, operator+() will be called twice, 2nd time with a temporary object a+b as its 1st argument. If the 1st parameter of operator+() is passed by value, then this 2nd addition involves moving instead of copying.

    Is the optimisation of the first example true if operator+ is implemented without operator+=?

    No, because in this case there is no copying inside operator+().