带有值引用的C ++运算符重载

时间:2013-11-20 02:42:30

标签: c++ c++11 operator-overloading

我正在重载向量运算符' - '并尝试使用差异引用方法。测试运算符的代码是

pos-(norm-bias)

其中pos,norm和bias是Vector类的所有实例。

常量参考工作:

Vector operator-(const Vector& v) {

但是,我不明白为什么没有'const'关键字会导致错误:二进制表达式的操作数无效。

Vector operator-(Vector& v) {

此外,我不明白为什么带有右值参考的“const Vector&& v”失败。

Vector operator-(const Vector&& v) {

2 个答案:

答案 0 :(得分:4)

您没有提供太多信息,因此我假设所有3个posnormbias都是Vector的实例。

让我们考虑表达式pos-(norm-bias)。首先,执行括号内的减法。您的operator-按值返回新的Vector对象。因此,第一次减法的结果现在将尝试绑定到pos.operator-()。但是rvalues无法绑定到非const引用,除非operator-通过const引用获取其参数,否则代码将无法编译。

现在,如果您将签名更改为Vector operator-(const Vector&& v),则第一个减法(norm - bias)将失败,因为bias是左值,并且它无法绑定右值参考参数。

您可能想要做的是提供两个重载,一个采用const引用,另一个采用右值引用。

Vector operator-(const Vector& v);
Vector operator-(Vector&& v);

在第二个运算符中,您可能会从参数中窃取资源,并避免内存分配等昂贵的操作。如果不知道你的Vector类包含什么,那么你是否真的可以从这样的重载中获益是不可能的。

答案 1 :(得分:0)

您想要的正确重载是:

Vector operator-(const Vector& v) const;
Vector operator-(Vector&& v) const;

请注意,您也希望将方法标记为const,否则当您使用(pos-norm)-bias这样的表达式时(无论该示例是否有意义),您将遇到更多问题。从长远来看,如果真的想要利用移动语义,你实际上想要做更多,因为左侧也可能是可移动的,你想用{{来完成运算符集合1}}。最后,您可能需要两个成员函数:

-=

和一组四个自由函数:

Vector& operator-=(const Vector& v);
Vector& operator-=(Vector&& v);

后者可以通过为您自动生成进一步改进/优化,考虑使用Boost.Operators或我的df.operators这样的库来帮助您。

通常,您可能希望阅读FAQ以获取运算符重载。