Возврат rvalue - что не так с этим кодом?

Я наткнулся на следующий фрагмент кода

std::string&& test()
{
    std::string m="Hello";
    return (std::move(m));
}

int main()
{
     std::string&& m = test();
}

Я понимаю, что приведенный выше код неверен и небезопасен, но я не уверен, почему. Пока это мое понимание кода. В функции test

  1. в стеке создается локальная переменная std::string с именем m.

  2. Затем эта строка возвращается, однако вместо копирования ее содержимое перемещается во временное хранилище. В этот момент функция test завершает вызов деструктора переменной m (содержимое которого было перемещено во временную папку).

  3. Теперь временное значение привязано к ссылке rvalue m. И насколько я понимаю, временное будет оставаться в живых до тех пор, пока его объект привязки не будет живым и в области видимости.

Может кто-нибудь, пожалуйста, скажите мне, где я могу ошибаться? Почему приведенный выше код небезопасен?


person James Franco    schedule 10.08.2015    source источник


Ответы (1)


Ссылка на rvalue по-прежнему является ссылкой, ваш код неверен по той же причине, что и функция, показанная ниже.

std::string& test()
{
    std::string m="Hello";
    return m;
}

В обоих случаях функция возвращает ссылку на локальную переменную. std::move не делает ничего, кроме приведения m к string&&, поэтому временно создал, что m в main затем привязывается к. Когда test завершается, локальная переменная уничтожается, а m становится висячей ссылкой.

Чтобы исправить свой код, измените тип возвращаемого значения с string&& на string.

std::string test()
{
    std::string m="Hello";
    return m;   // std::move is redundant, string will be moved automatically
}

int main()
{
     std::string&& m = test();
}

Теперь m в main может быть привязано к возвращаемому значению test, а время жизни этого продлено, чтобы соответствовать m .

person Praetorian    schedule 10.08.2015