C++ - 为什么要根据 op+= 而不是相反的方式来实现 op+?

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

为什么要这样实现:

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

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

比这个传播得更多:

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

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

我在阅读的文献中看到人们多次以这种方式实现它,而从来没有相反的方式,这到底是有什么原因吗,或者这只是一个偶然的巧合?

operator+ 必须创建一个新对象来保存结果。 operator+= 不需要新对象。

如果你用 operator+ 来写 operator+=,那么你最终会为额外的新对象创建、赋值(或交换)和销毁付出代价,所有这些你都没有不需要。

除此之外,在许多处理器上,硬件直接支持 += 和类似的操作,其中结果存储回输入寄存器之一,none 存储到第三个注册(如 +)。

顺便说一句,您的(原始的,现已编辑的)代码中存在一个错误,隐藏了部分额外工作。您实际上需要:

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

更糟糕的是,您的(又是原创的,现在已编辑)建议的 operator+ 实施未能正确 return 新对象,它 return 是一个悬空引用。那是未定义的行为。


对于那些感兴趣的人,第一个 operator+ 实现可以通过使用按值传递进一步改进:

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

现在如果 operator+ 的左手操作数是临时的,将使用移动构造函数,避免复制。尽管使用 NRVO,但无论哪种方式,结果代码可能都没有太大优势。