重载的“operator+”必须是一元或二元运算符错误

问题描述 投票:0回答:4

按照此答案中给出的建议,我在简单的 +

 类中重载了 
Point
 运算符,如下所示( += 重载工作正常)。

Point operator+ (Point p1, const Point& p2) { return std::move(p1 += p2); }

但是我收到一条错误消息

重载的'operator+'必须是一元或二元运算符(有3个参数)

出了什么问题?

c++ c++11 operator-overloading
4个回答
27
投票
听起来您已将运算符声明为成员函数。成员函数采用隐式第一个参数,这意味着您的运算符现在采用三个参数。您可以通过将其设为非成员函数来解决此问题。

无论如何,

最好将其声明为非成员,以确保操作的左右对称。

至于

std::move

,它位于<utility>
标题中。虽然我看不出在这里使用它的原因。 


17
投票
您想要执行以下任一操作:

// Member function, performs (*this + right) Point operator+ (Point & right)

// Free function, performs (left + right) Point operator+ (const Point &left, const Point& right)
    

3
投票
您将运算符设置为成员函数,这意味着当您包含隐式第一个

this

 参数时,它实际上具有三个参数。

要么:

    使用
  • *this
     而不是 
    p1
     并删除第一个参数,或者 
  • 让操作符重载一个自由函数(而不是成员)——这是首选。

0
投票
成员函数隐式接受

this

作为参数,

所以将

operator+

作为成员函数,应该只有一个显式参数:

void Point::operator+(const Point& rhs) { ... }
如果将

operator+

作为非成员函数,则应有两个参数:

Point operator+(Point& lhs, const Point& rhs) { ... }
对于

std::move

,它将右值引用转换为右值,并将lhs移动到返回值中,只有当lhs作为右值引用传递时才合理使用:

Point operator+(Point&& lhs, const Point& rhs) { lhs += rhs; return std::move(lhs); }
或者你可以考虑使用 std::forward,如果传递 lhs 作为左值引用和右值引用都退出:

template< typename T, typename = typename std::enable_if< std::is_same<Point, typename std::decay<T>::type>::value >::type> Point operator+(T&& lhs, const Point& rhs) { lhs += rhs; return std::forward<T>(lhs); // move rvalue into return value, copy lvalue }
请参阅 Scott Meyers 的 

Effective Modern C++ 第 25 项:在右值引用上使用 std::move

,在通用引用上使用 
std::forward

© www.soinside.com 2019 - 2024. All rights reserved.