Законен ли этот код? (Семантика перемещения C ++ 0x) - PullRequest
4 голосов
/ 20 июля 2011

Мне любопытно, является ли этот код допустимым в C ++ 0x. В частности, будет ли объект, объявленный в функции move_it(), правильно перемещен в объект, объявленный в main()?

#include <iostream>
#include <string>
#include <tr1/memory>
using namespace std;

class x
{
public:
    x() { cout << "create " << this << endl; }
    ~x() { cout << "destroy " << this << endl; }
};

x&& move_it()
{
    x r;
    return move(r);
}

int main()
{
    x n = move_it();
    return 0;
}

Ответы [ 3 ]

8 голосов
/ 20 июля 2011

Нет, он возвращает ссылку на локальный объект, точно так же, как и ссылку lvalue.

Просто верните его по значению, и пусть предполагаемый конструктор перемещения x заберет значение r.Когда вы возвращаете значение, возвращаемый объект является rvalue.

Если вам повезет, оптимизация NRVO включится (как и раньше) и в любом случае исключит копирование.

3 голосов
/ 20 июля 2011

Вы возвращаете висячую ссылку rvalue из move_it, которая вызывает неопределенное поведение при доступе к ней в main.

Если вы хотите переместить объект, измените тип возвращаемого значения на x и избавьтесь от перемещения:

x move_it()
{
    x r;
    return r;
}

(Автоматические переменные неявно обрабатываются как r-значения, когда возвращаются из функции.)

1 голос
/ 20 июля 2011

Как обычный пользователь, любой, кто не реализует библиотеку шаблонов, единственное использование для ссылок на r-значение, которое вы должны сделать, - это реализация конструкторов перемещения и назначения перемещения.

Посмотрите это видео http://channel9.msdn.com/Shows/Going+Deep/C9-Lectures-Stephan-T-Lavavej-Standard-Template-Library-STL-9-of-n

...