Frage

Wenn über Elemente eines Vektors Iterieren es bevorzugt, Iteratoren zu verwenden, anstatt eines Indexes (siehe Warum Verwendung Iteratoren statt Array-Indizes? ).

std::vector<T> vec;
std::vector<T>::iterator it;
for ( it = vec.begin(); it != vec.end(); ++it )
{
   // do work
}

Allerdings kann es erforderlich sein, den Index in dem Körper der Schleife zu verwenden. Welche der folgenden würde in diesem Fall vorzuziehen, wenn man bedenkt Leistung und Flexibilität / Erweiterbarkeit?

  1. Zurückkehren zum indiziert loop
    std::vector vec;
    size_t i;
    for ( i = 0; i < vec.size(); ++i )
    {
       // use i
    }
    
  2. berechnen offset
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = it - vec.begin(); 
       // use i
    }
    
  3. Verwenden Sie std :: Abstand
    std::vector vec;
    std::vector::iterator it;
    for ( it = vec.begin(); it != vec.end(); ++it )
    {
       size_t i = std::distance( vec.begin(), it );
       // use i
    }
    
War es hilfreich?

Lösung

Wenn Sie sich mit ausschließlich einen Vektor planen, möchten Sie vielleicht zurück in die indizierten Schleife wechseln, da es Ihre Absicht deutlicher als Iterator-Schleife vermittelt. Wenn jedoch die Evolution des Programms in der Zukunft zu einem Wechsel des Behälters führen kann, Sie zu den Iteratoren bleiben sollten und verwenden std :: Entfernung, die garantiert mit allen Standard-Iteratoren zu arbeiten.

Andere Tipps

Mit std :: Abstand ist ein bisschen mehr Generika, da es für alle Iteratoren arbeitet, nicht nur zufällige Access-Iteratoren. Und es sollte nur so schnell, wie es sein -. Vec.begin () bei Random Access Iteratoren

Es - vec.begin () ist im Grunde arithmetische Zeiger

.

std::distance(vec.begin(), it) geben Sie den Index it an zeigt, vorausgesetzt, es zeigt in vec.

Carl

Revert

an die indexierte Schleife.

Im Grunde genommen in 90% der Fälle sind Iteratoren überlegen, dies einer jener 10%. Durch die Verwendung eines Iterators Sie machen den Code komplexer und somit schwieriger zu verstehen, wenn der gesamte Grund für die Verwendung der Iterator in erster Linie um Ihren Code zu vereinfachen wurde.

Sie verpassen eine Lösung: einen Index für den Fall, halten Sie es brauchen, aber es nicht als Schleifenbedingung verwenden. funktioniert auch auf Listen, und die Kosten (pro Loop) sind O (n) und ein zusätzliches Register.

würde ich immer dazu neigen, mit Iteratoren für die zukünftige Entwicklung Gründe zu halten.

In dem obigen Beispiel, wenn Sie vielleicht std :: vector für std auslagern entschieden :: set (vielleicht brauchte man eine einzigartige Sammlung von Elementen), Iteratoren und Abstand mit () arbeiten würden.

ich mir ziemlich sicher, dass alle Performance-Probleme auf den Punkt optimiert werden würde davon vernachlässigbar zu sein.

Für Vektoren, verwende ich immer die ganze Zahl Methode. Jeder Index in den Vektor ist die gleiche Geschwindigkeit wie ein Array Lookup. Wenn ich schon den Wert viel zu verwenden, erzeuge ich einen Verweis darauf, für die Bequemlichkeit.

Vektor Iteratoren kann als ein Index in der Theorie etwas schneller sein, da sie Pointer-Arithmetik verwenden, um die Liste zu durchlaufen. Doch in der Regel finde ich, dass die Lesbarkeit wert ist die minimale Zeitunterschied.

Ich benutze Iteratoren für andere Behältertypen, und manchmal, wenn Sie die Schleifenvariable nicht benötigen. Aber wenn Sie die Schleifenvariable benötigen, tun Sie nichts außer machen Ihre Schleife schwieriger zu geben. (Ich kann nicht für c warten ++ 0x Automobil ..)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top