Вы можете вернуться по ссылке, если уверены, что указанный объект не выйдет из области видимости после выхода из функции, например, это ссылка на глобальный объект или функция-член, возвращающая ссылку на поля класса и т. Д.
Это возвращаемое правило ссылки одинаково как для lvalue, так и для rvalue.Разница в том, как вы хотите использовать возвращенную ссылку.Как я вижу, возвращение по rvalue-ссылке встречается редко.Если у вас есть функция:
Type&& func();
Вам не понравится такой код:
Type&& ref_a = func();
, потому что он эффективно определяет ref_a как Type &, так как именованная ссылка rvalue является lvalue, и никакого фактического перемещениябудет выполнено здесь.Это похоже на:
const Type& ref_a = func();
за исключением того, что фактический ref_a является неконстантной ссылкой на lvalue.
И это также не очень полезно, даже если вы напрямую передаете func () другой функции, которая принимает аргумент Type &&, потому что это все еще именованная ссылка внутри этой функции.
void anotherFunc(Type&& t) {
// t is a named reference
}
anotherFunc(func());
Отношение func() и anotherFunc () больше похожи на «авторизацию», согласно которой func () соглашается, что anotherFunc () может стать владельцем (или вы можете сказать «украсть») возвращаемого объекта из func ().Но это соглашение очень слабое.Неконстантная ссылка lvalue все еще может быть «украдена» вызывающими.На самом деле функции редко определяются, чтобы принимать rvalue ссылочные аргументы.Наиболее распространенным случаем является то, что «anotherFunc» является именем класса, а anotherFunc () фактически является конструктором перемещения.