2013-09-27 8 views
9

in C++ 11, wenn ich einen Bereich für Schleife auf Vektor basiert, wird es die Iteration Reihenfolge garantieren? sagen, werden die folgenden Codeblöcke für die gleiche Ausgabe garantiert?Bereichsbasierte für Schleife in C++ erhalten Sie die Indexreihenfolge

vector<T> output; 
vector<U> V; 
for(auto v: V) output.push_back(f(v)); 

vs

for(int i =0; i < V.size(); ++i) output.push_back(f(V[i])); 

was, wenn es nicht vector aber map etc?

+0

Sie könnten sicherlich ein bisschen eine unnötige Kopie optimieren, indem Sie 'auto &' anstelle von 'auto' –

Antwort

10

Ja, die beiden Codes sind garantiert identisch. Obwohl ich keinen Link zum Standard habe, können Sie einen Blick auf here werfen. Ich zitiere: You can read that as "for all x in v" going through starting with v.begin() and iterating to v.end().

+0

oder [hier] (http://msdn.microsoft.com/en-us/library/vstudio/jj203382.aspx) Führt die Anweisung wiederholt und ** sequentiell ** für jedes Element im Ausdruck aus. – qxixp

10

Ja und nein (Es hängt von dem Behälter in Gebrauch):

  • Der Bereich basierte für eine Schleife ist wie für (Iterator po = range.begin(); po = ! range.end(); ++ pos) {/ * mit einer Bereichsvariablen = * pos */...}
  • Ein Operator [] könnte etwas anderes machen (z. B. ein std :: map-Operator sucht nach einem den Schlüssel und einen neuen Eintrag erstellen, wenn der Schlüssel nicht vorhanden ist)

Beispiel:

#include <iostream> 
#include <map> 

int main() 
{ 
    typedef std::map<int, int> map; 
    map m = { { 0, 0 }, { 2, 2 }, { 4, 4 } }; 
    for(const auto& e : m) { 
     std::cout << e.first << " "; 
    } 
    std::cout << std::endl; 
    for(map::size_type i = 0; i < m.size(); ++i) { 
     std::cout << m[i] << " "; 
    } 
    std::cout << std::endl; 
    return 0; 
} 

Das Ergebnis ist:

0 2 4 
0 0 2 0 4 

(Das zweite Ergebnis könnte ein guter Schuss in den eigenen Fuß oder sogar beabsichtigt sein)

+4

Sie sollten wahrscheinlich darauf hinweisen, dass der Benutzer in diesem Beispiel in irgendeiner Weise etwas Unrecht tut. Wenn Sie sequentielle Indizes für eine 'map' mit dem Schlüsseltyp' int' haben, sollten Sie keine 'map' verwenden. Sie sollten ein' deque' oder 'vector' oder' array' verwenden. Wenn Sie keine sequentiellen Indizes haben, sollten Sie mit Iteratoren iterieren und nicht 'for (int i = 0; i OmnipotentEntity

10

Ja, sie sind gleichwertig. Die Standard-Garantien in 6.5.4:

Für eine bereichsbasierte für Anweisung der Form

für (für Bereichsdeklaration: Ausdruck) Anweisung

let range-init gleichwertig sein der Ausdruck durch Klammern (Ausdruck) umgeben

und für eine bereichsbasierte für Anweisung der Form

für (für Strecken-Erklärung: verspannt-init-Liste) statement

Lassen Sie range-init äquivalent zur braced-init-Liste sein. In jedem Fall ist eine bereichsbasierte für Aussage gleichwertig

{ 
    auto && __range = range-init; 
    for (auto __begin = begin-expr, 
     __end = end-expr; 
     __begin != __end; 
     ++__begin) { 
    for-range-declaration = *__begin; 
    statement 
    } 
} 

wo __range, __begin und __end Variablen für Exposition nur definiert sind, und _RangeT ist die Art des Ausdrucks, und BEGIN expr und Endausdruck werden wie folgt bestimmt: des Ausdrucks, und beginnen-expr und Endausdruck werden wie folgt bestimmt:

- wenn _RangeT ein Array-Typ ist, beginnen-expr und Endausdruck sind __range und __range + __bound, wobei __bound die Array-Grenze ist.Wenn _RangeT ein Array unbekannter Größe oder ein Array unvollständigen Typs ist, ist das Programm schlecht formatiert.

- wenn _RangeT ein Klassentyp ist, der unqualifizierte-IDs beginnen und endet, sind im Bereich der Klasse nachgeschlagen _RangeT wie von Klasse Member-Access-Lookup (3.4.5), und wenn entweder (oder beides) findet mindestens eine Deklaration, begin- expr und end-expr sind __range.begin() bzw. __range.end();

- sonst beginnen begin-expr und end-expr begin (_ range) und end ( _range) bzw. wo begin und end mit argumentabhängiger Suche (3.4.2) nachgeschlagen werden. Zum Zweck dieses Namens-Lookups ist Namespace std ein zugehöriger Namespace.

Obwohl Ihre Frage zu Karte ist ein bisschen unsinnig. Wenn es sich um eine geordnete Karte handelt und Sie die Karte richtig durchlaufen, sind sie gleichwertig. Wenn es sich um eine ungeordnete Karte handelt, macht Ihre Frage keinen Sinn.

Verwandte Themen