Something you hint at, but don’t quite say explicitly, is that the range-based for loop uses iterators under the hood. I believe this means that you cannot safely modify the container inside a range-based for loop, because you do not have access to the iterator in order to fix it the way you do in your explicit-iterator example.
It seems to be possible: https://stackoverflow.com/questions/6953128/need-iterator-when-using-ranged-based-for-loops but if you want that, why not type up an iterator loop?
Oh, I can’t imagine a situation in which you would actually want to do that.
When I first looked at that stackoverflow answer, I thought it was doing something weird and wonderful with the it iterator. However, they’re just manually incrementing their own iterator alongside the for-loop’s iterator. This does allow you access to an iterator, but it’s not the range-based for loop’s own iterator, so if you modify the container, then do something like your it = std::next(v.begin(), v.size() - 2); to ‘fix’ the iterator, the range-based for loop’s iterator will still be invalid.
it = std::next(v.begin(), v.size() - 2);
Again, modifying a container while iterating over it with a range-based for loop is not something I can imagine anyone doing. I just thought that since you’d introduced the three different types of for loop in the first half of your article, and then addressed how the first two behave when you modify the container, we might as well consider the third type as well. :)