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