As others mentioned, erase() will invalidate the iterator that you give it (and possibly /all/ iterators, depending on the container). In general, it is best to avoid erasing unless you have to; use bulk clear()s instead. And you should only erase at the end of your processing, because all your iterators may become invalid.
std::copy() is very useful, and I suggest using it whenever possible. To move a whole container, use copy and then clear; to move a range, use copy and then erase(rangestart, rangeend).
Monster has the right idea in his reply, but "it = erase(it)" is non-standard behavior on many types of containers. It works for sequences (vector, list, deque) but not for associative containers (set, map). I think that Microsoft allows it for sets, but I'm pretty sure that other STL implementations do not. "erase(it++)" is the preferred notation for associative containers.
If you need to erase some elements but not others, you can use the following:
Code: Select all
containertype::iterator it;
for (it = container.begin(); it != container.end(); ) {
do_something(*it);
if (want_to_delete_it) {
it = erase(it); // use this for vectors, lists, deques
//erase(it++); // use this for maps, sets, multimaps
} else {
it++;
}
}
(If you're wondering about why "erase(it++)" ever works, remember that the postfix++ is equivalent to {old = it; ++it; return old;} ... think about it!)
Also, FYI: vector, deque, and list are definately NOT all contiguous. Vector and deque are contiguous, so that insertions/deletions in the middle are slow but access is fast; list is not contiguous, so access is a little slower in the middle but deletions are very fast.
To find out more about what is allowed after an erase() and what isn't, read the STL documentation for each container class to see what actions invalidate iterators, and how many iterators are affected for each type of container.
http://www.sgi.com/tech/stl/ is a fantastic reference; I suggest you bookmark it
