根据 此cppreference页,通过值传递重载二进制运算符的第一个参数,以某种方式优化了表达式,如 a + b + c
. 链接页面的相关代码片段如下。
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)
}
};
我有两个问题
a + b + c
表达式经此优化?X
还覆盖了复制和移动赋值操作符和构造函数,那么像 x = a + b
产生任何复制?为什么会产生复制?我不知道这是否有那个例子编写者的想法,但有一些解释。考虑一下这段代码中发生了什么。
X a, b, c;
X d = a + b + c;
这里,首先, a + b
基本上被评价为 operator+(operator+(a, b), c)
. 注意到 operator+(a, b)
是一个 r值因此, lhs
可以,在外在应用 operator+
,通过以下方式初始化 移动施工人员.
另一种实施方式 operator+
就...而言 operator+=
如下所示。
friend X operator+(const X& lhs, const X& rhs)
{
X temp(lhs);
temp += rhs;
return temp;
}
请注意,你需要创建一个临时对象,因为你需要一个对象来申请 operator+=
上。有了这个解决方案,这两种应用的 operator+
在 operator+(operator+(a, b), c)
涉及 抄写员.
现场演示。https:/godbolt.orgz5Dq7jF
当然,你可以添加第二个版本,用于 r值 如下。
friend X operator+(X&& lhs, const X& rhs)
{
lhs += rhs;
return std::move(lhs);
}
但这比原来的值传递版本需要更多的输入。
一般来说,通过值传递经常被用于想要统一lvalues和rvalues的重载的情况下;例如,寻找一下 统派运算符.