Я достаточно хорошо понимаю, как работают ссылки на 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 тоже?
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
, но это не доступно для других контейнеров. Для других контейнеров вы останетесь с вышеупомянутым подходом, где стоимость структуры контейнера данных должна быть взята, хотя стоимость создания хранимых данных можно избежать.
Ты хочешь std::make_move_iterator()
:
L.insert(
insertPoint,
std::make_move_iterator(R.begin()),
std::make_move_iterator(R.end())
);