Re: std::list remove element mid iteration
 
On Dec 20, 2:10 am, red floyd <no.s...@here.dude> wrote:
Christopher wrote:
The situation is that a std::list<std::set<std::string> > is being
iterated through. Upon certain criteria some sets become empty. I need
to remove the empty sets from the list.
Is it safe to iterate through a list and call list::erase( iterator )
in mid iteration?
Well, you can use
struct set_is_empty
{
     bool operator()(const std::set& s) const { return s.empty(); }
};
std::erase(std::remove_if(l.begin(), l.end(), set_is_empty());
Which could be unnecessarily expensive.  In the case of
std::list, the canonical form is:
    l.remove_if( set_is_empty() ) ;
However, the original poster said that sets "become" empty
during his iteration, so this can't be used.
or else, the canonical iteration for this list is:
for (it = l.begin(); it != l.end(); )
    if (it->empty())
       it = l.erase(it);
    else
       ++it;
Adopted to his case, you'd add braces and put the if at the end
of the loop.  (Also, I'd write this with a while, rather than a
for.  Something like:
    std::list<...>::iterator iter = l.begin() ;
    while ( iter != l.end() ) {
        //  processing...
        if ( iter->empty() ) {
            iter = l.erase( iter ) ;
        } else {
            ++ iter ;
        }
    }
I'd prefer even more if that if could be replaced with a ?: on
the right side of an assignment, since the most important aspect
here is the update of the iterator, and not how it's being
updated, but I can't think of a nice way of doing this off hand.
--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34