Это допустимое преобразование?
Да. Внутри функции-члена *this
всегда имеет lvalue. Даже если функция квалифицирована по ссылке rvalue. Это то же самое, что и
void foo(bar& b) { /* do things */ }
void foo(bar&& b) {
// b is an lvalue inside the function
foo(b); // calls the first overload
}
. Таким образом, вы можете использовать функцию с определением lvalue ref для совместного использования реализации.
И использование std::move
в результате также не проблема. Первая перегрузка может вернуть только ссылку lvalue, потому что, насколько ей известно, она была вызвана для lvalue. Между тем, вторая перегрузка имеет дополнительный бит информации, она знает, что изначально была вызвана для rvalue. Следовательно, он выполняет дополнительное приведение на основе дополнительной информации.
std::move
- это просто именованное приведение, которое превращает lvalue в rvalue. Его цель состоит в том, чтобы указать, что назначенный объект может рассматриваться как истекающий. Поскольку вы выполняете это приведение внутри контекста, о котором вы знаете, что это правда (член изначально вызывается для объекта, который привязывается к ссылке rvalue), это не должно создавать проблемы.