Keeping it low-key this week, let's re-iterate (lol) the conventional map-erase idiom in C++.

Iterating through the elements of a std::map is easy enough, but complication arises when you want to delete a few elements as you go.

The first naive approach might look a little like this:

Unfortunately, after you've erased the element from the map, the iterator pointing to it is invalidated. When the loop goes to run ++it ready for the next iteration, this invokes UB… meaning you should never do it. It's invalid.

So what to do? If you do ++it before performing the erase, then it's safe, but then you don't have the iterator to erase any more. You can use a copy:

Note the important change to the for declaration. The increment on each loop is replaced by the conditional increment in the body.

A shorter version of the same thing is:

This works because it++ inherently makes a copy, performing the increment after the original value is sent to erase, but before the erase actually occurs.

Coming soon…

Other standard containers make this a lot easier; the next C++ standard, due for completion this year (or possibly in 2012), will fix this omission for std::map by allowing m.erase to return the next iterator automatically: