Reputation: 16195
Following the advice given in this answer, I have overloaded the +
operator in my simple Point
class as follows (the += overload works fine).
Point operator+ (Point p1, const Point& p2)
{
return std::move(p1 += p2);
}
But I get an error saying
overloaded 'operator+' must be a unary or binary operator (has 3 parameters)
What is wrong?
Upvotes: 25
Views: 32964
Reputation: 126
The member function implicitly takes this
as a parameter,
So take operator+
as a member function, should only have one explicit parameter:
void Point::operator+(const Point& rhs)
{
...
}
And if take operator+
as a non-member function, sholud have two parameters:
Point operator+(Point& lhs, const Point& rhs)
{
...
}
And for std::move
, it casts rvalue reference to rvalue, and move lhs into return value, only reasonable to use when lhs passed as rvalue reference:
Point operator+(Point&& lhs, const Point& rhs)
{
lhs += rhs;
return std::move(lhs);
}
Or you may consider use std::forward, if pass lhs as lvalue reference and rvalue reference both exits:
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
}
Refer to Effective Modern C++ by Scott Meyers item 25: Use std::move
on rvalue references, std::forward
on universal references.
Upvotes: 0
Reputation: 63775
You want to do either:
// Member function, performs (*this + right)
Point operator+ (Point & right)
or
// Free function, performs (left + right)
Point operator+ (const Point &left, const Point& right)
Upvotes: 17
Reputation: 385144
You made the operator a member function, meaning it actually has three parameters when you include the implicit first this
parameter.
Either:
*this
rather than p1
and get rid of that first parameter, orUpvotes: 3
Reputation: 227410
It sounds like you have declared your operator as a member function. A member function takes an implicit first parameter, meaning your operator now takes three parameters. You can fix this by making it a non-member function.
In any case, it is preferable to declare it as a non-member, to ensure symmetry between the LHS and the RHS of the operation.
As for std::move
, it is in the <utility>
header. Although I can't see the reason to use it here.
Upvotes: 29