Sonderbares Verhalten eines Iterators



  • Hallo ihr,

    Mein C++ Programm beinhaltet unter anderem einen Vektor, welcher Vektoren enthaelt, die Strings enthalten.
    Auf diesen Vektor lasse ich um Werte in ihm zu aendern einen Iterator zeigen.
    Das tue ich auf die folgende Art und Weise:

    cliext::vector<cliext::vector<System::String^>>::iterator start = vec->begin();
    

    *start muesste jetzt meines Wissens nach einen Vektor mit Strings zurueckliefern.
    start muesste die Adresse auf einen Vektor mit Strings zurueckliefern.
    start[0] muesste einen String zurueckliefern.

    Sonderbarerweise liege ich falsch, denn start[0] liefert wieder nur einen Vektor zurueck, waerend erst start[0][0] einen String zurueckliefert.
    So kann ich zwar gut arbeiten, aber ich verstehe nicht aus welchem Grund das so ist, denn bisher habe ich immer geglaubt man wuerde mit '++' und '--' durch die verschiedenen Vektoren iterieren, die der grosse Vektor enthaelt und dann durch EINEN einfachen Index auf den String zugreifen.

    Scheint aber nicht der Fall zu sein.
    Kann sich jemand diese Anomalie erklaeren?

    tschuess

    David



  • 777 schrieb:

    ...

    cliext::vector<cliext::vector<System::String^>>::iterator start = vec->begin();
    

    *start muesste jetzt meines Wissens nach einen Vektor mit Strings zurueckliefern.

    Würde ich auch so sehen, start[0] gibt aber vermutlich nicht das erwartete zurück. Wie wäre es mit (*start)[0]?

    Ganz davon abgesehen: Ist C++/CLI schon soweit mit zwei direkt folgenden schließenden Template-"klammern" klar zu kommen? In C++ ist obiges jedenfalls noch nicht portabel zu verwenden, hier müsste man ein Leerzeichen: "> >" einfügen (Auch wenn einige Compiler es auch schon beherrschen).

    cu André



  • Wie wäre es mit (*start)[0]?

    Das funktioniert jetzt sogar - eigentlich auch logisch.
    Dennoch wuesste ich gerne, was 'start' fuer ein Objekt ist, wenn es
    nicht gerade dereferenziert ist.
    Denn wie ich bereits gesagt habe hat ein:

    (*start)[0] = "JOJO";
    

    die selbe Wirkung, wie ein:

    start[0][0] = "JOJO";
    

    Wobei in beiden Versionen start natuerlich noch nicht mit '++' Inkrementiert wurde.
    Nur 'start' scheint also nix anderes zu sein als ein Zeiger auf das ganze Objekt.
    Nicht auf einen Teilvektor sondern auf das komplette Vektorobjekt.
    Nur durch das referenzieren wird es scheinbar auf ein Objekt des 'Obervektors' beschraenkt.



  • 777 schrieb:

    Dennoch wuesste ich gerne, was 'start' fuer ein Objekt ist, wenn es
    nicht gerade dereferenziert ist.

    Ein Iterator.

    In C++ kann dies bei z.B. std::vector auch ein Zeiger sein, davon gehe ich aber bei C++/CLI nicht aus, und auch unter C++ ist dies bei vielen Containern nicht der Fall.

    *iterator ist nur in sofern definiert, das er das Element liefert auf den der Iterator (wie auch immer verweist). Ähnliches Verhalten bauen unter C++ die Smartpointer nach.

    777 schrieb:

    Sie scheint absolut unabhaengig davon zu sein, was mit stutzig macht, da ich geglaubt habe ein inkrementieren wuerde einen Adresssprung bewirken, der so gross ist wie die groesse des Objektes.

    In C++ (nicht CLI) wird ++ beim Vektor vermutlich tatsächlich ein Zeiger sein, und damit ein Adresssprung um die Größe machen. Bei Managed-Objekten könnte dies anders sein (Zumindestens wäre es denkbar das durch Aktivitäten des GC der Speicher verschoben wird). In C++ ist auch nur definiert, das ++ um ein Element weitergeht (übrigens ist das Gegenstück -- auch nicht bei allen Iteratorarten definiert).

    cu André



  • Mhh gut zu wissen.
    Allerdings glaube ich jetzt verstanden zu haben, wie der Iterator funktinoiert.
    Habe da ein bisschen herum gespielt und es erscheint jetzt alles logisch.
    Vielen Dank fuer deine Hilfe. 🙂 😃 😉 😃 🙂 😉 🙂 😃


Anmelden zum Antworten