Нет, это не правильно. Вы попали в обычную ловушку, которую делаете один, когда обнаружили ссылку на значение, как и Мотти в принятом ответе! (И я тоже сделал эту ошибку, в моем предыдущем тесте с rref)
Если вы не хотите стрелять себе в ногу при работе с rref, усвойте это:
В большинстве случаев функция, возвращающая ссылку на значение, так же глупа, как и функция, возвращающая нормальную ссылку.
Потому что ссылки на rvalue являются ... ссылками! Поэтому, если вы вернете ссылку - rvalue или нет - на message
, вы вернете ссылку на объект, который был просто уничтожен, потому что он вышел из области видимости, поэтому вы возвращаете висячую ссылку. Это ошибка.
Кроме того, не пишите return std::move(message)
, потому что компилятор уже знает, что message
- это временное значение (значение), поэтому нет необходимости изменять его с помощью std :: move. И на самом деле, написание return std::move(something)
может предотвратить оптимизацию (по крайней мере на MSVC10, кажется, отключить RVO).
Итак, правильный и самый эффективный способ:
#include <string>
std::string foo (void)
{
std::string message ("Hello!");
return message;
}
void bar (const std::string& message2)
{
if (message2 == "Bye Bye!")
return;
}
int main ()
{
bar (foo());
}
Старый добрый C ++ 03:)
Потому что NRVO начинает действовать, и нет ни копии, ни движения, только одна конструкция.