Dekrementieren von begin() (bidirektional)
-
Hallo,
ich habe ein seltsames Phänomen beim Dekrementieren des begin() Iterators einer map entdeckt, und wollte mal fragen, was es damit auf sich hat.
Folgender Code funktioniert wie erwartet unter MSVC++10, MSVC++11, g++ 4.6.1, d. h. der begin() Iterator, der anfangs auf die m[1] zeigt, zeigt nach dem Dekrementieren auf end().
#include <map> #include <cassert> int main() { std::map<int, int> m; m[1] = 1; m[2] = 2; m[3] = 3; std::map<int, int>::iterator it = m.begin(); --it; assert(it == m.end()); return 0; }
Entfernt man jetzt z. B. die Zeile "m[3] = 3;", so funktioniert obiges Beispiel zwar unter MSVC++ Versionen immer noch wie erwartet, bei g++ 4.6.1 bleibt der Iterator aber auch nach dem Dekrementieren auf begin().
Ist das ein Bug?
Oder was hat es damit auf sich?
-
Undefiniertes Verhalten. Du darfst
begin()
nicht dekrementieren.Was eine spezifische Implementierung für Eigenheiten aufweist, ist irrelevant. Sie kann sich von Version zu Version ändern, und unterscheidet sich -- wie du siehst -- bei verschiedenen Compilern. Folglich kannst du dich nicht auf ein bestimmtes Verhalten verlassen. Ist hier aber kein grosser Verlust...
-
Und wo genau kann man den Standard nachgucken, um zu sehen, dass das Dekrementieren von begin() nicht klar definiert ist?
-
Auf http://www.open-std.org/ kannst du dir die Drafts ansehen. Aber was erwartest du bei der Dekrementierung von
begin()
für ein Resultat? Ich sehe nicht ein, wozu man sowas tun wollte...
-
Danke!
Weil der Iterator für einen gesuchten Term steht und end() == "Nicht Gefunden" bedeutet. (Und da --it die letzte Operation bei mir ist, soll ein Dekrementieren "Nicht Gefunden" bedeuten, falls it gleich begin() ist.)
-
Falls du rückwärts iterieren willst, wären die Methoden
rbegin()
undrend()
etwas für dich. Aberstd::map
hat auch einfind()
.Und falls du was ganz Spezielles baust, kannst du ja immer noch mit
if
aufbegin()
prüfen und in diesem Fallend()
zuweisen.