reverse_iterator + erase



  • ich hab' die folgende schleife, die eine std::list von proxies durchläuft, jeder proxy kann bei seinem Aufruf angeben, daß er aus der Liste entfernt werden möchte.

    for(list::iterator it=list.begin(); it != list.end(); )
    {
      bool removeThis = (*it)->CallHandler();
      if (removeThis)
         it = list.erase(it);
      else
         ++it;
    }
    

    Sollte ja so fiunktionieren.

    Jetzt möchte ich die Liste rückwärts durchlaufen -

    for(list::reverse_iterator it = list.rbegin(); it != list.rend(); )
    {
      bool removeThis = (*it)->CallHandler();
      if (removeThis)
         ... // [1] ???
      else
         ++it;
    }
    

    1. ist das so richtig?
    2. was schreib' ich an [1] ?

    dankeschön schonmal im voraus



  • Wie wär's mit genau dem gleichen Konstrukt? Der rückt ja nur den übergeben Iterator weiter, löscht das alte Element und gibt das weitergerückte Teil zurück. Daß weiterrücken bei Dir halt ein Schritt zurück bedeutet macht doch keinen Unterschied.



  • erase nimmt nur keinen reverse_iterator...



  • moin

    Du kannst mit reverse() die Liste einfach umdrehen.

    Warum muß das unbeding rückwarts sein? Du durchläufts doch so oder so die komplette Liste. 😕



  • Weil ich einmal vorwärts und einmal rückwärts durch muß



  • Na dann nimm doch reverse():

    for(list::iterator it=list.begin(); it != list.end(); )
    {
      bool removeThis = (*it)->CallHandler();
      if (removeThis)
         it = list.erase(it);
      else
         ++it;
    } 
    
    list.reverse()
    
    for(list::iterator it=list.begin(); it != list.end(); )
    {
      bool removeThis = (*it)->CallHandler();
      if (removeThis)
         it = list.erase(it);
      else
         ++it;
    }
    

    sollte doch eigentlich funktionieren... :p



  • Eventuell geht die folgende Variante:

    if( removeThis) {
      list::iterator pos = it.base();
      --pos;
      pos = list.erase( pos);
      it = list::reverse_iterator( pos);
    }
    else {
      ++it;
    }
    

    base konvertiert die Position des reverse Iterators in die entsprechende Position des normalen Iterators. Die inhaltliche Position ist bei einem reverse Iterator aber ungleich der physikalischen Position. Daher ist die Korrektur notwendig. Am besten sich die reverse Iteratoren sicherheitshalber nochmal im Lieblings STL Buch anschauen 🙂



  • Besitzen die reverse_iterator nicht eine MEthode um sie in den gleichwertigen iterator zu verwandeln? base glaub ich hieß die.



  • @Bongolus: wäre OK, wenn ich niht andauernd durch müßte.. 🤡

    @niemand: danke, das sieht ja schonmal ganz gut aus. Jetzt muß ich nur noch rausfinden, wieviele plus/minus-einse da fehlen....



  • 2. was schreib' ich an [1] ?

    list.erase((++it).base());
    

    Die näherliegende Alternative:

    list.erase(--it.base());
    

    hat den Nachteil, dass sich potentiell bei std::vector und std::string nicht funktioniert. Hier können Iteratoren simple Zeiger sein und solche sind als Rückgabewerte unveränderbar.



  • Hab grad "niemands" code ausprobiert, scheint auch im praktischen Leben zu funktionieren 🙂

    @Hume: sieht genauso aus, oder? nur der "fortsetzungsiterator" fehlt noch.

    Dankeschön.


Log in to reply