October 04, 2006
The thinnest of threads
You have an iterator that refers to an element of an associative container. How do you erase that element and advance the iterator to the position that follows it?
For a vector, it's easy:
iter = container.erase(iter);
However, in general, erase does not return a value. How does one find the next position?
The obvious way doesn't work:
container.erase(iter); ++iter;
because after you've called erase, iter is invalid. Therefore you can't increment it.
If you had a second iterator, say iter2, you could do this:
iter2 = iter; ++iter; container.erase(iter2);
Because you incremented iter before you call erase, iter now refers to a different position in the container. Therefore the call to erase won't invalidate iter.
We can simplify this code by the clever observation that so long as we never care about using iter2 again, this example has exactly the same effect as
container.erase(iter++);
The reason is that the effect of iter++ is to copy iter somewhere else, then increment iter, and finally yield the copy of the previous value of iter as its result. This copy therefore behaves exactly the same as would iter2. Moreover, because a function's arguments must necessarily be evaluated before the function begins execution, there is no worry about order of evaluation.
This technique hangs by the thinnest of threads; I would ordinarily hesitate to recommend it for that reason. However, it is so much more succinct than any alternative I have found that I think it deserves wider recognition.
Posted by Andrew Koenig at 04:01 PM Permalink
|