C++: Erasing Elements in a Set

Recommended Posts

DaTroof    162
I have a routine that iterates through a set of object pointers, and performs a function that determines whether the element should be removed. It looks something like this:
set<foo*>::iterator i = container.begin();
foo* bar;
while (i != container.end()) {
bar = *i;
if (bar->execute() == 0) {
i++;
} else {
container.erase(i);
i = container.upper_bound(bar);
}
}


This is the best way I could conceive to remove elements from the set while iterating through it, the main problem being that I don't see another way to keep the iterator valid after the erase(). Is there a better method?

Share on other sites
_the_phantom_    11250
doesnt erase return an iterator?

Share on other sites
SiCrane    11839
Not in for std::set in standard C++, though some vendors have std::set::erase() return an iterator anyways. Anyways one way to handle this is to make a copy of the iterator, increment that and then erase the old iterator.

Share on other sites
DaTroof    162
Quote:
 Original post by SiCraneNot in for std::set in standard C++, though some vendors have std::set::erase() return an iterator anyways. Anyways one way to handle this is to make a copy of the iterator, increment that and then erase the old iterator.

Yes, the std::set::erase() I'm using doesn't return an iterator. Copying the iterator is probably more efficient than an upper_bound check, so I'll try that instead. Thanks.

Share on other sites
Talria    102
You could maintain iterator to previous element (prev_i, initially container.end()) and do:
if(prev_i==container.end())  i=container.begin();else{  i=prev_i;  ++i;}

once it's being removed from the set.

Edit: Or what SiCrane suggested. It's actually better option.