Does moving a vector invalidate iterators?

c++, c++11, iterator

Solution

While it might be reasonable to assume that `iterator`s are still valid after a `move`, I don't think the Standard actually guarantees this. Therefore, the iterators are in an undefined state after the `move`.

There is no reference I can find in the Standard which specifically states that iterators that existed before a `move` are still valid after the `move`.

On the surface, it would seem to be perfectly reasonable to assume that an `iterator` is typically implemented as pointers in to the controlled sequence. If that's the case, then the iterators would still be valid after the `move`.

But the implementation of an `iterator` is implementation-defined. Meaning, so long as the `iterator` on a particular platform meets the requirements set forth by the Standard, it can be implemented in any way whatsoever. It could, in theory, be implemented as a combination of a pointer back to the `vector` class along with an index. If that's the case, then the iterators would become invalid after the `move`.

Whether or not an `iterator` is actually implemented this way is irrelevant. It could be implemented this way, so without a specific guarantee from the Standard that post-`move` iterators are still valid, you cannot assume that they are. Bear in mind also that there is such a guarantee for iterators after a `swap`. This was specifically clarified from the previous Standard. Perhaps it was simply an oversight of the Std comittee to not make a similar clarification for iterators after a `move`, but in any case there is no such guarantee.

Therefore, the long and the short of it is you can't assume your iterators are still good after a `move`.

EDIT:

23.2.1/11 in Draft n3242 states that:

Unless otherwise specified (either explicitly or by defining a function in terms of other functions), invoking a container member function or passing a container as an argument to a library function shall not invalidate iterators to, or change the values of, objects within that container.

This might lead one to conclude that the iterators are valid after a `move`, but I disagree. In your example code, `a_iter` was an iterator in to the `vector` `a`. After the `move`, that container, `a` has certainly been changed. My conclusion is the above clause does not apply in this case.

Problem

If I have an iterator into vector `a`, then I move-construct or move-assign vector `b` from `a`, does that iterator still point to the same element (now in vector `b`)? Here's what I mean in code: ``` #include <vector> #include <iostream> int main(int argc, char *argv[]) { std::vector<int>::iterator a_iter; std::vector<int> b; { std::vector<int> a{1, 2, 3, 4, 5}; a_iter = a.begin() + 2; b = std::move(a); } std::cout << *a_iter << std::endl; // Is a_iter valid here? return 0; } ``` Is `a_iter` still valid since `a` has been moved into `b`, or is the iterator invalidated by the move? For reference, `std::vector::swap` does not invalidate iterators.

Original source

Related problems