A range-based for
loop is equivalent to, approximately: 1) get the container's beginning and ending iterator, 2) Use a temporary iterator to iterate from the beginning iterator value to the ending iterator value 3) On each iteration, dereference the temporary iterator and set the range loop's variable to the dereferenced iterator value.
... more or less. The bottom line is 1) a range-based for loop obtains and uses the beginning and the ending iterators for the range, and 2) you state that your container is a vector, and, as you know, modifying a vector is going to invalidate most iterators to the contents of the vector.
It is true that with certain kinds of modifications to the contents of the vector, certain iterators will not be invalidated, and will remain valid. But, practically, it is safe to assume that if you've got a std::vector::iterator
or a std::vector::const_iterator
somewhere, modifying a vector means that the iterator is no longer valid. Not always 100% true, as I mentioned, but that's a pretty safe assumption to make.
And since range iteration obtains and uses iterators to the container, for the lifetime of the iteration, that makes, pretty much, doing a range iteration over a vector, and modifying the vector during iteration, a non-starter. Any modifications to the vector will likely result in undefined behavior, for any continuing iteration over the vector.
Note that "modification" means, essentially, insertion or removal of values from the vector; that is, modification of the vector itself. Modifying the values in the vector has no effect on the validity of any existing iterators, and this is safe.
If you want to iterate over a vector, and then safely modify the vector during this process (with the modification consisting of inserting or removing value from the vector), the first question you have to answer yourself is what does the insertion or removal mean for your iteration. That's something that you have to figure out yourself. If, for example, your loop is currently on the 4th element in the vector, and you insert a new 2nd value in the vector, since inserting a value into the vector shifts all the remaining values in the vector up, the 4th element in the vector will become the 5th element in the vector, and if you manage to safely do this correctly, on the next iteration, the 5th element in the vector will be the same one you just iterated over previously. Is this what you want? That's something you will have to answer yourself, first.
But as far as safely modifying a vector during iteration, the most simplest way is to avoid using iterators entirely, and use an index variable:
for (size_t i=0; i<x.size(); ++i)
{
auto v=x[i];
// ...
}
Now, modifying the vector is perfectly safe, and all you have to figure out, then, is what has to happen after the vector gets modified, whether the i
index variable needs adjusting, in any way.
And that question you'll have to answer yourself.