Является ли возвращение ссылкой rvalue более эффективным?

например:

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

Ответ 1

Beta_ab&&
Beta::toAB() const {
    return move(Beta_ab(1, 1));
}

Это возвращает ссылку на болтовню, как в случае с ссылочным случаем lvalue. После возвращения функции временный объект будет разрушен. Вы должны вернуть значение Beta_ab по значению, например, следующее

Beta_ab
Beta::toAB() const {
    return Beta_ab(1, 1);
}

Теперь он правильно перемещает временный объект Beta_ab в возвращаемое значение функции. Если компилятор может, он вообще избежит перемещения, используя RVO (оптимизация возвращаемого значения). Теперь вы можете сделать следующее

Beta_ab ab = others.toAB();

И он переместит временную конструкцию в ab или сделает RVO, чтобы полностью исключить выполнение или скопировать. Я рекомендую вам прочитать BoostCon09 Rvalue References 101, который объясняет это, и как (N) RVO взаимодействует с этим.


Ваш случай возвращения ссылки rvalue будет хорошей идеей в других случаях. Представьте, что у вас есть функция getAB(), которую вы часто вызываете на временной. Не оптимально заставить его возвращать ссылку const lvalue для временных значений rvalue. Вы можете реализовать его так:

struct Beta {
  Beta_ab ab;
  Beta_ab const& getAB() const& { return ab; }
  Beta_ab && getAB() && { return move(ab); }
};

Обратите внимание, что move в этом случае не является необязательным, потому что ab не является ни локальным автоматическим, ни временным значением r. Теперь ref-qualifier && говорит, что вторая функция вызывается в rvalue temporaries, делая следующий шаг, вместо копирования

Beta_ab ab = Beta().getAB();