Liste durchlaufen und Elemente löschen



  • Hallo

    Ich habe folgende Frage:
    Ich möchte eine Liste durchlaufen und bei den einzelnen Elementen eine Variable prüfen, ist diese false, soll das Element gelöscht werden. Ich versuche das so:

    for(itList = List.begin(); itList!=List.end; ++itList)
       if(itList->Variable == false)
           List.erase(itList);
    

    Das Problem ist aber, dass er sich immer aufhängt, weil er sagt:

    list iterator not incrementable
    

    Ich kann mir schon denken, dass das Problem darin liegt, dass er versucht die Schleife weiterdurchlaufen, aber sich die Anzahl der Elemente in der Schleife geändert haben. Da ich noch nicht so oft mit std::list gearbeitet habe, bräuchte ich kluge Tipps, wie man das machen könnte. (meine Alternative hat leider auch nicht geklappt)

    Danke
    chrische



  • itList = Liste.erase(itList);
    

    Erase liefert einen Iterator auf das nächste gültige Element nach dem Löschen. Du darfst dann itList allerdings nicht mehr inkrementieren, sonst wird ein Element ausgelassen...

    EDIT:
    Oder direkt in einem durch 😉

    erase(remove_if(Liste.begin(), Liste.end(), !boost::bind(&ListenTyp::Variable, _1)), Liste.end());
    


  • Hallo

    Wenn ich ehrlich sein soll, habe ich nicht kapiert, wie ich mein Problem lösen kann.

    chrische



  • Hallo,

    hier mal was konstruktives von mir für dich 😉

    #include <iostream>
    #include <list>
    
    using namespace std;
    
    struct Foo {
      Foo(bool b_) : b(b_) {}
      bool b;
    };
    
    int main() {
      list<Foo> l;
      l.push_back(true);
      l.push_back(false);
      l.push_back(true);
      l.push_back(true);
      l.push_back(false);
    
      list<Foo>::iterator it = l.begin();
      for ( ; it != l.end(); ) {
        if ( it->b == false)
          l.erase(it++);
        else
          ++it;
      }
    
      it = l.begin();
      for ( ; it != l.end(); ++it)
        cout<<it->b<<'\n';
    
      return 0;
    };
    

    Keine Garantie, nur kurz zusammengestümpert 🙂

    MfG

    GPC



  • @chrische5:

    Du hast richtig erkannt, dass Du die Liste nicht weiter durchlaufen kannst, weil der Iterator auf das gelöschte Element ungültig geworden ist. Ich schreibe dass erase einen gültigen Iterator auf das Element nach dem gelöschten zurückgibt. Wo ist das Problem, das in der Schleife umzusetzen und nur zu inkrementieren wenn nicht gelöscht wird?

    BTW:
    GPC's Version macht in etwa dasselbe nur dass er selbst den Iterator auf das nächste gültige Element inkrementiert bevor der alte Iterator gelöscht wird.



  • LordJaxom schrieb:

    BTW:
    GPC's Version macht in etwa dasselbe nur dass er selbst den Iterator auf das nächste gültige Element inkrementiert bevor der alte Iterator gelöscht wird.

    Und dass es nicht wirklich funktioniert.

    // Test:
    
    l.push_back(false);
    l.push_back(false);
    


  • schon gut, so ändere man sie doch folgenermaßen ab:

    for ( ; it != l.end(); ) {
        if ( it->b == false)
          l.erase(it++);
        else
          ++it;
      }
    

    MfG

    GPC


Log in to reply