Какой тип std :: move? - PullRequest
       7

Какой тип std :: move?

4 голосов
/ 19 декабря 2011

Этот код работает должным образом (онлайн здесь ).В конце v пусто и w не пусто, так как воровало содержимое v.

    vector<int> v;
    v.push_back(1);
    cout << "v.size(): " << v.size() << endl;
    auto vp = move(v);
    vector<int> w(vp);
    cout << "w.size(): " << w.size() << endl;
    cout << "v.size(): " << v.size() << endl;

Но если я заменю auto vp=move(v) на

    vector<int> && vp = move (v);

, тогда он не будет двигаться.Вместо этого он копирует, и оба вектора не пусты в конце.Как показано здесь .

Разъяснение: Более конкретно, что является автоматически производным типом vp?Если это не vector<int> &&, то что еще это может быть?Почему два примера дают разные результаты, несмотря на то, что они очень похожи?

Extra : я тоже попробовал это, и он все равно копировался вместо перемещения

    std :: remove_reference< vector<int> > :: type && vp = move(v);

Ответы [ 3 ]

12 голосов
/ 19 декабря 2011

Редактировать для пояснения ОП : auto -обработанный тип move(v) равен vector<int>.См. C ++ 11 «автоматическая» семантика .

Первый пример делает это:

move 'v' into 'vp'
copy 'vp' into 'w'

, а второй пример делает это:

set 'vp' as rvalue-reference of 'v'
copy 'vp' (which is 'v') into 'w'

Что std:move делает, просто приводит тип к rvalue (см. Что такое std :: move () и когда его следует использовать? ).Поэтому в

vector<int>&& vp = move(v);

он просто устанавливает для rvalue-reference vp значение v и больше ничего не делает.Кроме того, rvalue-ссылка - это lvalue (у него есть имя), поэтому

vector<int> w(vp);

вызовет конструктор копирования для копирования vp (то есть v) в w.

Он вызовет конструктор перемещения, если вы сделаете vp значение r ( Пример ):

vector<int> w(move(vp))

Возможно, вы захотите прочитать это: *Объяснение 1040 * C ++ Rvalue .

2 голосов
/ 19 декабря 2011

В первом случае:

auto vp = move(v);

эквивалентно:

vector<int> vp = move(v);

Это вызывает конструктор перемещения, поскольку move(v) имеет тип vector<int>&&, следовательно, vpзаканчивает воровкой содержимого v.

Во втором случае:

vector<int>&& vp = move(v);

просто делает vp значением r-ссылки на v.Это не приводит к вызову конструктора перемещения или конструктора копирования, и ничто не воровано.

1 голос
/ 19 декабря 2011
auto vp = move(v);

Создает новый vector<int> и вызывает его конструктор перемещения:

vector(const vector<T>&& other);

, который украдет содержимое v.

Так типа 'vp'просто vector<int> .. никаких ссылок не задействовано:

vector<int> vp;

Это «перемещение» внутренних органов ... не самого фактического вектора.

Так что &vp будет отличаться от &v .. но содержимое переместится.

...