C ++ 11 перемещение одного вектора в другой - передача ссылки на rvalue в конструктор - PullRequest
0 голосов
/ 25 марта 2019

Я пытаюсь понять семантику перемещения C ++, std::move() и ссылки на rvalue.

Я реализовал этот пример.

#include <iostream>
#include <vector>

int main()
{
  int totalSize = 6;

  std::vector<double> oldData{ 10, 20, 30 }; 

  oldData.resize(totalSize, 0);

  std::vector<double> newData(std::move(oldData));
  return 0;
}

Я хотел бы знать, действительно ли этодвижущийся вектор oldData в newData или копирование происходит под колпаком.

1 Ответ

1 голос
/ 25 марта 2019

Предполагая, что вы исправите бесконечный цикл в:

  for(unsigned i = 0; i < totalSize - oldData.size(); ++i)
    oldData.push_back(0);

И напишите что-то вроде:

  for(unsigned i = oldData.size(); i < totalSize; ++i)
    oldData.push_back(0);

или, еще лучше:

  oldData.resize(totalSize, 0);

Затем std::move переместит все данные с oldData на newData. Вот цитата из cppreference :

6) Переместить конструктор. Создает контейнер с содержимым другие используют семантику перемещения. Распределитель получен путем перемещения от распределителя, принадлежащего другому. После переезда другой гарантированно будет пустым ().

7) Конструктор перемещения с расширенным распределением. Использование alloc в качестве распределителя для нового контейнера, перемещение содержимого из другого; если alloc! = other.get_allocator (), это приводит к поэтапному перемещению. (в этом случае не гарантируется, что other будет пустым после перемещения)

В вашем конкретном случае вектор имеет распределитель по умолчанию, что означает, что применяется только пункт (6). Однако, если кто-то передает распределитель, все становится интереснее.

Вот остальные ссылки на тему сложность :

6) Константа.

7) Линейный, если alloc! = Other.get_allocator (), в противном случае постоянный.

Опять же, в вашем случае сложность O (1), но с распределителями все становится интереснее.

Заключение : внутреннее представление должно перемещать постоянное число указателей в O (1), а не перемещать элементы один за другим. Можно реализовать вектор с одним указателем с целыми числами емкости и размера или тремя указателями (начало, конец и конец емкости). И для всех этих реализаций перемещение - это простая игра с указателями.

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

...