I understand reasonably well how rvalue references work, but I'm not exactly sure how they work with iterators in the STL. Here's something that I want:
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
}
Now I know that std::list has a splice method. But I want to know if this can work at all. Can it work for deque too?
The splice
and moving the contents of the containers are different operations. In the case of splice
(which cannot be done with deque
) the whole node is transferred from one container to the other. The nodes will no longer be in the original container, and no allocations will be performed by the operation.
The alternative of moving the contents with an algorithm similar to the one you stated, but using a move iterator:
L.insert(insertPoint,
std::make_move_iterator(R.begin()),
std::make_move_iterator(R.end()));
This will work for both list
and deque
but the semantics are different. The insertion to the new list will require the allocation of std::distance(R.begin(),R.end())
nodes, the contents of which will be filled by moving from the original container. That reduces the cost of the creation of the new nodes, but they need to be allocated nonetheless. Note that the old list will still contain all the nodes, although they will be empty as the contents of the data have been moved.
In the case of std::list
you should prefer splice
, but that is not available on other containers. For other containers you will be left with the approach above, where the cost of building the container data structure has to be taken, although the cost of the creation of the stored data can be avoided.
You want std::make_move_iterator()
:
L.insert(
insertPoint,
std::make_move_iterator(R.begin()),
std::make_move_iterator(R.end())
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With