Re: Problems removing an element from a std::set using a reverse_iterator
On 7/23/07 11:37 AM, in article
1185208334.915753.252110@r34g2000hsd.googlegroups.com, "irotas"
<google@irotas.net> wrote:
Again, in my original post I presented two alternatives suggested by
Scott Meyers:
1) v.erase(--ri.base());
2) v.erase((++ri).base());
Option #1 compiles and (seemingly) executes properly. That is, the
output is as expected, and valgrind doesn't complain. However, Option
#2 (the option Meyers' asserts is preferred) does not produce correct
output, and valgrind complains profusely. Therefore, one of the goals
of this thread was to determine if this advice in Meyers' "Effective
STL" is in fact flawed.
And the determination is that Meyer's advice is not flawed - both calls to
erase() work fine. But as has already been pointed out, one of these calls
also invalidates ri. Valgrind starts to complain only after the program has
incremented this invalid iterator and passed it a -second- time in a call to
erase().
Furthermore, it makes little sense to erase items in a way that would work
for any Standard container - instead of in the way optimally suited for the
container the items are actually in (which in this case is a std::set). And
the preferred way for erasing a range of items in a std::set is to combine
lower_bound() and upper_bound() in a call to erase() like this:
uis.erase( uis.lower_bound(5), uis.upper_bound(9) );
Certainly no other technique can match this one's efficiency, conciseness
and correctness.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]