std::vector<T>::insert and std::move_iterator<T> how they work together?

Viewed 230

I am not exactly sure about this, so please explain me how does it work.

Let's consider following code.

std::vector<std::string> vec {};
 
void add (std::vector<std::string>&& v) {
    using iter = std::vector<std::string>::iterator;
    vec.insert (vec.end (), 
                std::move_iterator<iter> (v.begin ()), 
                std::move_iterator<iter> (v.end ()));
}

Are all elements of v going to be moved? std::vector<T>::insert() for the range version requires first and last iterators, so having the code like this how can it know that v.begin()+1 has also to be moved? Is the implementation of std::vector<T>::insert() distinguish between "normal" and "move" iterators?

1 Answers

[Does] the implementation of std::vector<T>::insert() distinguish between "normal" and "move" iterators?

No. The "magic" happens in move_iterator::operator*(): it returns an rvalue reference. Therefore, when insert() fills in a newly allocated element, it prefers the move-constructor, and for this reason moves the values.

So, yes, you can be sure that *(v.begin()+1) has been moved after the operation.

Related