Передача rvalue ссылок между функциями - PullRequest
0 голосов
/ 17 ноября 2018

Я реализую перегрузки операторов сравнения для определенного класса foo:

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

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

Однако при вызове оператора != я получаю следующую ошибку компиляции:

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);
                        ^~~

Что мне кажется странным, потому что перегрузка оператора == принимает в качестве аргументов ссылки на rvalue, так почему именно компилятор пытается их разыменовать?

PS: я понимаю, что я мог бы решить эту проблему, просто передав объекты как const &, но для целей проектирования ссылки на значения лучше иметь смысл (foo - это вложенный вспомогательный класс, экземпляр которого не предполагается создавать вне определения базового класса) .

1 Ответ

0 голосов
/ 17 ноября 2018

Выражения lhs и rhs являются выражениями lvalue внутри bool operator!=(foo&& lhs, foo&& rhs){. Это не связано с ссылочным типом переменных.

Как говорится в сообщении, lvalue не может быть привязан к rvalue-reference, и поэтому перегрузка bool operator==(foo&& lhs, foo&& rhs){ не может рассматриваться.

Если вы хотите получить rvalue из lvalue, чтобы он мог связываться с rvalue-reference, вы должны использовать std::move:

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