Search code examples
c++listiteratorerase

C++ : deleting multiple elements of a list while iterating the list


I know how do erase elements of a list, and that erase return a valid iterater. My problem is, that I want to remove not just one element but multiple.

Actuall my code is like

 for(list<Treenode*>::iterator it=currentLevel->begin(); it!=currentLevel->end(); ++it){
     if(something(*it))  {
         for(list<Treenode*>::iterator it2=currentNewLevel->begin();it2!=currentNewLevel->end();){
             if (somethingDifferent(*it2)) {
                 it2=currentLevel->erase(it2);
             } else {
                 ++it2;
             }
         }
     }
 }

of course this could not work, because it is not changed. I don't know how to change the iterator but stay on this iteration-step.

Thank you for reading. I hope someone know the answer.


Solution

  • In general, the way to remove elements from a list based depending on a condition is to use the std::list::remove_if member function.

    bool pred(const Treenode* t) { .... }
    currentNewLevel.remove_if(pred);
    

    The predicate can be a functor, so it can keep any state that is required to implement the removal criteria:

    #include <algorithm> // for std::find_if
    #include <list>
    
    // unary predicate functor. Returns true if an element of a reference
    // list satisfies "something" and the functor call argument satisfies "somethingDifferent"
    struct Pred
    {
      Pred(const std::list<Treenode*>& nodes) : nodes_(nodes) {}
      bool (const Treenode* t) const
      {
        return std::find_if(nodes_.begin(), nodes_.end(), something) != nodes_.end() &&
               somethingDifferent(t);
      }
     private:
      const std::list<Treenode*>& nodes_;
    };
    

    then

    Pred p(currentLevel);
    currentLevel.remove_if(p);