Iterator zwischenspeichern



  • Hallo!

    Es liegen Daten in einer

    std::multimap<size_t, size_t>
    

    vor, die in eine Liste eingetragen werden sollen. Jedes Item hat einen Index und kann noch zusätzlichen einen belibiegen Wert vom Typ long (uData) speichern.
    Wenn ein Eintrag aus der Liste gewählt wird um ihn anzuzeigen, zu bearbeiten etc. müssen die Daten vorher aus der multimap geholt werden werden.

    Dazu gehe ich bisher wie folgt vor.

    // Funktion wird aufgerufen wenn ein Item gewählt wurde
    void GetItem(Item * pItem)
    {
      std::multimap<size_t, size_t>::const_iterator Iter = MyMap.begin();
    
      for (size_t i = 0; i < pItem->iIndex; i++)
          Iter++;
    
      // Funktion die die Daten verarbeitet
      Foo(Iter->first, Iter->second);
    }
    

    Dieses Umweg über die Schleife und das Inkrementieren des Iterators finde ich ziemlich umständlich. Gibt es eine Möglichkeit den Iterator (Position, Zeiger, irgendwas) in uData (siehe oben) zwischenzuspeichern und ihn dann damit in der Funktion GetItem zu initialisieren?

    Schönen Gruß
    Olaf



  • Geht nicht folgendes?

    Foo((MyMap.begin() + pItem->iIndex)->first, 
        (MyMap.begin() + pItem->iIndex)->second);
    


  • Fellhuhn schrieb:

    Geht nicht folgendes?

    Foo((MyMap.begin() + pItem->iIndex)->first, 
        (MyMap.begin() + pItem->iIndex)->second);
    

    Nein, leider nicht. Maps habe keinen wahlfreien Zugriff sondern sind bidirektional.



  • void GetItem(Item * pItem)
    {
      std::multimap<size_t, size_t>::const_iterator Iter = MyMap.find(pItem->iIndex);
    
      // Funktion die die Daten verarbeitet
      Foo(Iter->first, Iter->second);
    }
    

    //edit ahh hab mich verlesen. das erste size_t der map ist nicht derselbe index wie der in pItem?



  • otze schrieb:

    //edit ahh hab mich verlesen. das erste size_t der map ist nicht derselbe index wie der in pItem?

    Doch, eigentlich schon. Aber da es eine Multimap ist, bringt suchen nach dem Index (Schlüssel) nichts, da es mehrere Elemente mit dem gleichem Schlüssel gibt.



  • std::advance



  • LordJaxom schrieb:

    std::advance

    Habe ich vorher auch schon probiert, jedoch einen nicht initilierten INterator übergeben. Dann wurde eine Ausnahme geworfen.

    advance ist ja auch nur eine Schleife ähnlich wie ich sie habe. Bringt es trotzdem Vorteile std::advance zu nutzen?

    Olaf



  • Es brächte dann Vorteile, wenn Du irgendwann mal auf vector oder deque wechselst, da dort die Verschiebung durch eine einfache Addition statt über eine Schleife gemacht werden kann.



  • LordJaxom schrieb:

    Es brächte dann Vorteile, wenn Du irgendwann mal auf vector oder deque wechselst, da dort die Verschiebung durch eine einfache Addition statt über eine Schleife gemacht werden kann.

    Ein Wechsel ist nicht vorgesehen, da ich Schlüssel/Wert Paare benötige.
    Recht herzlichen Dank auch.

    Olaf



  • Olaf.100 schrieb:

    Bringt es trotzdem Vorteile std::advance zu nutzen?

    - Du hast in deinem Code keine unschoenen Schleifen stehen -> der Code ist kuerzer und uebersichtlicher.
    - Bei einer Schleife muesste ein fremder Leser (z.B. du in 5 Monaten) erst nachvollziehen, was in der Schleife passiert - std::advance sollte jedem bekannt sein -> der Code ist schneller verstaendlich und daher besser wartbar.
    - reuse - du benutzt mit std::advance fertigen Code, der zigmal getestet ist und korrekt arbeitet. In einer eigenen Schleifenimplementation koennen sich leichter Tippfehler, logische Fehler usw. einschleichen -> der Code ist sicherer und schneller implementiert.

    Reicht das an Vorteilen? 😉



  • Den Iterator zwischenzuspeichern darfst du nur, wenn sich die Map nicht mehr ändert (weil dadurch sich ja die Index-Reihenfolge ändern könnte).

    Ich verstehe auch irgendwie deinen Ansatz nicht richtig.
    Auf eine (Multi)map greift man ja normalerweise mithilfe des Schlüssels zu (und nicht über einen Index, weil dann könntest du ja gleich einen std::vector o.ä. benutzen).

    Ich nehme aber mal an, du hast ein ListBox o.ä.
    Warum verknüpfst du deine Listeneinträge dann nicht direkt mit den Items (du brauchst doch gar nicht den Zwischenweg über die Map gehen)?


Anmelden zum Antworten