为什么 C++ 中重载二元算术运算符的规范实现按值通过了第一次争论?
Why does cannonical implementation of overloading binary arithmatic operator in C++ pass first arguement by value?
根据 this cppreference page,按值传递重载二元运算符的第一个参数以某种方式优化了表达式,如 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)
}
};
关于这个我有 2 个问题:
- 链式
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)
是一个 rvalue,因此,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)
中的两个应用程序都涉及 copy-constructor.
现场演示:https://godbolt.org/z/5Dq7jF
当然,你可以为rvalues添加第二个版本,如下:
friend X operator+(X&& lhs, const X& rhs)
{
lhs += rhs;
return std::move(lhs);
}
但这比原来的值传递版本需要更多的输入。
一般情况下,值传递常用于需要统一左值和右值重载的情况;例如,查找 统一赋值运算符.
根据 this cppreference page,按值传递重载二元运算符的第一个参数以某种方式优化了表达式,如 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)
}
};
关于这个我有 2 个问题:
- 链式
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)
是一个 rvalue,因此,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)
中的两个应用程序都涉及 copy-constructor.
现场演示:https://godbolt.org/z/5Dq7jF
当然,你可以为rvalues添加第二个版本,如下:
friend X operator+(X&& lhs, const X& rhs)
{
lhs += rhs;
return std::move(lhs);
}
但这比原来的值传递版本需要更多的输入。
一般情况下,值传递常用于需要统一左值和右值重载的情况;例如,查找 统一赋值运算符.