C++ C++;-为什么要实施op+;就op+;=而不是反过来?

C++ C++;-为什么要实施op+;就op+;=而不是反过来?,c++,operator-overloading,code-reuse,C++,Operator Overloading,Code Reuse,为什么这一实施: 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 ) { *thi

为什么这一实施:

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+=
,那么你最终需要支付额外的新对象创建、分配(或交换)和销毁费用,所有这些都是你不需要的

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

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

T& T::operator+=( const T& rhs )
{
    *this = *this + rhs; // creation of temporary, move assignment, and destruction of temporary
    return *this;
}
更糟糕的是,您建议的
operator+
实现(同样是原始的,现在已编辑)未能正确返回新对象,而是返回一个悬空引用。这是未定义的行为


对于那些感兴趣的人,第一个
操作符+
实现可以通过使用pass-by-value进一步改进:

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

现在,如果
运算符+
的左操作数是临时的,则将使用move构造函数,以避免复制。尽管使用NRVO,结果代码可能没有多大优势。

测试第二个,您会发现它不起作用。它究竟是如何工作的将取决于
/。。。实现…
,但它不起作用。很可能,
返回*this+rhs
将完全无法解决此问题。@user2357112:我的答案是否解释了您发现的问题,或者是否还有其他问题?请不要通过查看答案来更改帖子。它会给出答案useless@user2357112下面的答案是肯定的。很晚了;我没想清楚。很抱歉弄错了。@BenVoigt:是的,你的答案似乎解决了所有问题。但是我们不是创建了一个新对象吗?我们在一种情况下创建T temp,在另一种情况下创建一些结果。@ennmael:operator+=的直接实现中没有创建新对象的东西。考虑到
std::complex
,它看起来像
T&std::complex::operator+=(const std::complex&rhs){re+=rhs.re;im+=rhs.im;return*this;}
没有创建新的临时变量,每个语句都精确地映射到单个CPU指令(在通用架构上)@Ennmael:如果你问
操作符+
(不是
+=
)的两种变体是否都创建了一个临时对象,是的,这是必要的。这也是我的答案开头所说的。您建议的方法存在效率极低的问题。
+=
。非常感谢!我现在明白了。在我的版本中,运算符+保持不变,只是我的运算符+=更差,因为它执行了额外的复制操作。@Yakk参数首先不应符合条件。