joaocandre
joaocandre

Reputation: 1745

Passing rvalue references between functions

I'm implementing comparison operator overloads for a particular class foo:

class foo{
public:
    foo() {};
};

bool operator==(foo&& lhs, foo&& rhs){
    // ...
    return true;
}
bool operator!=(foo&& lhs, foo&& rhs){
    return operator==(lhs,rhs);
}

However, when calling the != operator, I get the following compilation error:

tester.cpp: In function ‘bool operator!=(foo&&, foo&&)’:
tester.cpp:37:27: error: no matching function for call to ‘operator==(foo&, foo&)’
  return operator==(lhs,rhs);
                           ^
tester.cpp:33:6: note: candidate: ‘bool operator==(foo&&, foo&&)’ <near match>
 bool operator==(foo&& lhs, foo&& rhs){
      ^~~~~~~~
tester.cpp:33:6: note:   conversion of argument 2 would be ill-formed:
tester.cpp:37:24: error: cannot bind rvalue reference of type ‘foo&&’ to lvalue of type ‘foo’
  return operator==(lhs,rhs);
                        ^~~

Which seems strange to me because the == operator overload takes rvalue references as arguments, so why exactly is the compiler trying to dereference them?

PS: I understand I could solve this by just passing the objects as const &, but for design purposes rvalue references would make more sense (foo is a nested helper class no supposed to be instantiated outside base class definition).

Upvotes: 0

Views: 658

Answers (1)

user10605163
user10605163

Reputation:

The expressions lhs and rhs are lvalue expressions inside bool operator!=(foo&& lhs, foo&& rhs){. This is unrelated to the reference type of variables.

As the message says, a lvalue cannot be bound to a rvalue-reference and therefore the overload bool operator==(foo&& lhs, foo&& rhs){ cannot be considered.

If you want to get a rvalue from a lvalue, so it can bind to the rvalue-reference, you are supposed to use std::move:

bool operator!=(foo&& lhs, foo&& rhs){
    return operator==(std::move(lhs), std::move(rhs));
}

Upvotes: 5

Related Questions