C++ 为什么在C++;按值传递第一个参数?
根据,通过值传递重载二进制运算符的第一个参数以某种方式优化表达式,如C++ 为什么在C++;按值传递第一个参数?,c++,operator-overloading,C++,Operator Overloading,根据,通过值传递重载二进制运算符的第一个参数以某种方式优化表达式,如a+b+c。链接页面中的相关代码段如下所示: friend X operator+(const X& lhs, const X& rhs) { X temp(lhs); temp += rhs; return temp; } friend X operator+(X&& lhs, const X& rhs) { lhs += rhs; r
a+b+c
。链接页面中的相关代码段如下所示:
friend X operator+(const X& lhs, const X& rhs)
{
X temp(lhs);
temp += rhs;
return temp;
}
friend X operator+(X&& lhs, const X& rhs)
{
lhs += rhs;
return std::move(lhs);
}
X类
{
公众:
X&operator+=(const X&rhs)//复合赋值(不需要是成员,
{//但通常是修改私有成员)
/*将rhs添加到*此操作在此处进行*/
return*this;//通过引用返回结果
}
//在类主体中定义的朋友是内联的,并且在非ADL查找中隐藏
friend X操作符+(X lhs,//通过值传递lhs有助于优化链接的a+b+c
const X&rhs)//否则,两个参数都可能是const引用
{
lhs+=rhs;//重用复合赋值
return lhs;//按值返回结果(使用move构造函数)
}
};
关于这一点,我有两个问题:
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)
是一个右值,因此,lhs
可以在operator+
的外部应用程序中由move构造函数初始化
根据operator+=
实现operator+
的替代方法如下:
friend X operator+(const X& lhs, const X& rhs)
{
X temp(lhs);
temp += rhs;
return temp;
}
friend X operator+(X&& lhs, const X& rhs)
{
lhs += rhs;
return std::move(lhs);
}
请注意,您需要创建一个临时对象,因为您需要一个对象来应用operator+=
。使用此解决方案,operator+(operator+(a,b),c)
中的operator+
的两个应用程序都涉及复制构造函数
现场演示:
当然,您可以为右值添加第二个版本,如下所示:
friend X operator+(const X& lhs, const X& rhs)
{
X temp(lhs);
temp += rhs;
return temp;
}
friend X operator+(X&& lhs, const X& rhs)
{
lhs += rhs;
return std::move(lhs);
}
但这需要比原始值传递版本更多的输入
通常,在需要统一左值和右值的重载的情况下,经常使用按值传递;例如,寻找统一赋值运算符。但是,如果我们在语句上使用值传递版本,如
xa,b;xc=a+b
,调用复制构造函数是否正确?例如,在上面链接的代码中,输出CMM5
表示当计算operator+(a,b)
时,调用复制构造函数将a
的值复制到operator+
的参数中,对吗?@Diggs我相信是这样的。一定有副本。当两个操作数都是左值时,您不能仅通过移动来实现它。@Diggs您可能也感兴趣。我创建了一个单独的重载,因为它处理一个相关但不同的问题(在一种情况下,操作符+
有两个重载—一个用于左值,一个用于右值)。