为什么在其他人的代码中重载 += 从来没有 return nothing?

Why overloading of += never return nothing in other people's code?

假设我有一个非常简单的 class

class C { 
    private:
        int _a; 
        int _b; 
    public:
        C (int a, int b) :_a { a }, _b { b } {}
        int a () { return _a; }
        int b () { return _b; }
        bool operator== (C c) {
            return this->_a == c.a() && this->_b == c.b();
        }
};

我想重载运算符 += 这样

C foo(8, 42);
C bar(1, 1); 
C zoo(9, 43);
foo += bar;
assert(foo == zoo);

运行良好。

据我阅读其他人的代码,我应该写这样的东西

C operator+= (C c) {
    return { this->_a += c.a(), this->_b += c.b() };
}

但据我了解,return下载一些东西是没有用的。事实上,即使我将 += 重载为

,上面的断言也不会失败
void operator+= (C c) {
    this->_a += c.a();
    this->_b += c.b();
}

C operator+= (C c) {
    this->_a += c.a();
    this->_b += c.b();
    return C(0,0);
}

TL;DR: 为什么我在重载 += 时不应该 return 无效?

+= 的预期行为是它评估为自己的第一个操作数(x += y 中的 x),作为随后可以分配给的值。这就是 += 对内置类型的工作方式,一般来说,自定义运算符的行为应该像内置运算符一样,除非您有特定的原因(例如 operator<<operator>> I/O).

这意味着实现应该如下所示:

C &operator+= (C c) {
    this->_a += c.a();
    this->_b += c.b();
    return *this;
}

表示用户可以编写

这样的代码
if ((foo += bar) == zoo) { ... }

(foo += bar) += baz;

内置类型是可能的,并且有时(尽管不经常)实际上很有用。

你的断言说的是 operator+= 的副作用,而不是它的结果,这就是为什么你没有注意到基于 return 类型的任何可能的差异。

返回表达式的左侧允许您链接运算符,或在一行中使用赋值的结果,即

int c = a += b;//this is so ugly :'(

if(a+=b)
{
}

此外,这是您将在内置类型(c++ 标准的第 13.6 段)中拥有的行为,因此最好为您的所有自定义类模仿它