c ++ 11 переместить вставку для std :: deque или std :: list

Я достаточно хорошо понимаю, как работают ссылки на rvalue, но я не совсем уверен, как они работают с итераторами в STL. Вот что я хочу:

void insertList(std::list<int>& L, std::list<int>&& R, std::list<int>::iterator insertPoint)
{
L.insert(insertPoint, R.begin(), R.end()); // want to use move semantics
}

Теперь я знаю, что в std :: list есть метод соединения. Но я хочу знать, может ли это вообще сработать. Может ли это работать на deque тоже?

8

Решение

splice а также перемещение содержимое контейнеров различных операций. В случае splice (что не может быть сделано с deque) весь узел переносится из одного контейнера в другой. Узлы больше не будут находиться в исходном контейнере, и операция не будет распределяться.

Альтернатива перемещение содержимое с алгоритмом, аналогичным указанному вами, но с использованием переехать итератор:

L.insert(insertPoint,
std::make_move_iterator(R.begin()),
std::make_move_iterator(R.end()));

Это будет работать для обоих list а также deque но семантика другая. Включение в новый список потребует выделения std::distance(R.begin(),R.end()) узлы, содержимое которых будет заполняться путем перемещения из исходного контейнера. Это снижает стоимость создания новых узлов, но, тем не менее, их необходимо распределять. Обратите внимание, что старый список будет по-прежнему содержать все узлы, хотя они будут пустой как содержимое данных было перемещено.

В случае std::list ты должен предпочесть splice, но это не доступно для других контейнеров. Для других контейнеров вы останетесь с вышеупомянутым подходом, где стоимость структуры контейнера данных должна быть взята, хотя стоимость создания хранимых данных можно избежать.

12

Другие решения

Ты хочешь std::make_move_iterator():

L.insert(
insertPoint,
std::make_move_iterator(R.begin()),
std::make_move_iterator(R.end())
);
5

По вопросам рекламы [email protected]