Range-based-for oder Iterator?
-
Angenommen ich habe einen Vector...
std::vector<int> sampleData = { 1, 2, 3, 4, 5 };Für welche der folgenden Varianten sollte ich mich entscheiden?
Variante 1:
for (auto& element : sampleData) { // Do something with element }Variante 2:
for (auto& element = sampleData.begin(); element != sampleData.end(); ++element) { // Do something with *element }Welche Variante hat ihre Vor- und Nachteile? Oder ist es einfach Geschmackssache?
-
Iteratoren wuerde ich nur nehmen, wenn ich sie innerhalb der Schleife brauche, z.B. um ein Element zu loeschen.
-
Denke immer dran, dass es auch transform, copy, accumulate etc. gibt. Je nach Schleifeninhalt lieber ein Lambda verwenden.
-
Die beiden Funktionen sind fast identisch.
Variante 1 ist übersichtlicher und in manchen Fällen vielleicht sogar ein bisschen schneller, dafür hast du keinen Zugriff auf die iteratoren.
-
So einfach wie möglich. Wenn du für alle Elemente etwas tust und keinen Zugriff auf den Iterator brauchst, nimm Range-Based For. Ist möglicherweise auch schneller als eine Iteratoren-Schleife, da
end()garantiert nicht mehr als einmal aufgerufen wird.In deinem zweiten Beispielcode sollte übrigens
autostattauto&stehen, du kannst keine Non-Const-LValue-Referenzen an RValues binden.
-
du kannst keine Non-Const-LValue-Referenzen an RValues binden
Doch, ist eine Spezialitaet von VS.
-
Nexus schrieb:
Ist möglicherweise auch schneller als eine Iteratoren-Schleife, da
end()garantiert nicht mehr als einmal aufgerufen wird.Die Aussage ist mir nicht ganz klar, was meinst du damit?
Die Pruefung gegen .end muss doch bei jedem Element erfolgen oder meinst du, dass er sich den Wert von .end nur einmal holt und sich dann merkt?
-
letzteres
Für die Iterator-Schreibweise muss der Compiler erstmal beweisen, dass end() während der Schleife konstant ist.
-
decimad schrieb:
letzteres
Für die Iterator-Schreibweise muss der Compiler erstmal beweisen, dass end() während der Schleife konstant ist.
Entschuldige die erneute Nachfrage aber ich moechte es komplett verstehen.
Warum muss der compiler beweisen, das .end() konstant ist?
-
Ah, weil der compiler nicht ausschliessen kann, dass waehrend der for loop etwas in den Vector gepushed wird, oder?
-
-
Ja, auch wenn ich es nicht so ausdrücken würde. Der Compiler wird wahrscheinlich nicht danach schauen, ob da ein "push_back"-Aufruf stattfindet... das wäre irgendwie viel zu speziell. Der wird sich den Zustand des Objekts anschauen, von dem end() abhängt und dann schauen, ob sich dieser Zustand über die Ausdrücke in den Schleifendurchläufen verändern kann.