Why does cannonical implementation of overloading binary arithmatic operator in C++ pass first arguement by value?

半世苍凉 提交于 2020-06-27 12:44:06

问题


According to this cppreference page, passing the first argument of an overloaded binary operator by value somehow optimizes expressions like a + b + c. The relevant code snippet from the linked page is as follows:

class X
{
 public:
  X& operator+=(const X& rhs)         // compound assignment (does not need to be a member,
  {                                   // but often is, to modify the private members)
    /* addition of rhs to *this takes place here */
    return *this;                     // return the result by reference
  }

  // friends defined inside class body are inline and are hidden from non-ADL lookup
  friend X operator+(X lhs,           // passing lhs by value helps optimize chained a+b+c
                     const X& rhs)    // otherwise, both parameters may be const references
  {
    lhs += rhs;                       // reuse compound assignment
    return lhs;                       // return the result by value (uses move constructor)
  }
};

I have 2 questions regarding this:

  1. How are chained a + b + c expressions optimized by this?
  2. Assuming X also overrides the copy and move assignment operators and constructors, would a statement like x = a + b produce any copying? Why or why not?

回答1:


I don't know whether this had that example-writer in mind, but have some explanation. Consider what happens in this code:

X a, b, c;
X d = a + b + c;

Here, first, a + b is evaluated basically as operator+(operator+(a, b), c). Note that operator+(a, b) is an rvalue, and therefore, lhs can, in the outer application of operator+, be initialized by move-constructor.

An alternative how to implement operator+ in terms of operator+= is as follows:

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

Note that you need to create a temporary since you need an object to apply operator+= on. With this solution, both applications of operator+ in operator+(operator+(a, b), c) involves copy-constructor.

Live demo: https://godbolt.org/z/5Dq7jF

Of course, you can add a second version for rvalues as follows:

friend X operator+(X&& lhs, const X& rhs) 
{    
   lhs += rhs;
   return std::move(lhs);
}

But this requires much more typing than the original value-passing version.


Generally, passing by value is frequently used in situations where you want to unify overloads for lvalues and rvalues; for example, look for unified assignment operator.



来源:https://stackoverflow.com/questions/62177743/why-does-cannonical-implementation-of-overloading-binary-arithmatic-operator-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!