2010-12-07 5 views
1

Sagen wir, ich habe diesen Code:Wie kann ein Iterator dereferenziert werden, wenn sein Vektor hinzugefügt wird?

std::vector<Object*> objects; 
std::vector<Object*>::iterator iter; 
for (iter = objects.begin(); iter != objects.end(); iter++) { 
    if (condition) 
     objects.push_back(new Object()); 
} 

Wenn jedoch push_back auftritt, iter undereferenceable wird. Ohne iter zurückzusetzen, wie halte ich es dereferenzierbar? Wenn ich es zurücksetzen muss, gibt es eine einfache Möglichkeit, es so zu machen, dass es wieder dahin zurückgeht, wo es vorher war?

+0

Als eine Randnotiz gibt es einen möglichen logischen Fehler in dieser Idee in dem, wenn Sie Objekte an das Ende hinzufügen, während Sie iterieren, ist es möglich, dass Sie in eine Endlosschleife gelangen, wie mehr und mehr Objekte hinzugefügt und Iteration nie beendet (es gibt immer ein anderes Objekt, zu dem man iterieren kann!) – MerickOWA

Antwort

5

Ich würde empfehlen, dass Sie einfach per Index darauf zugreifen. Dies beseitigt das Problem vollständig.

0

Sie müssen einen altmodischen for-Schleife mit numerischen Indizes führen. Entweder das oder reserve() den Vektor, bevor die Schleife läuft, um zu garantieren, dass sie nicht skaliert.

Auch rohe Zeiger? Srl.

0

Der Iterator wird nur ungültig, wenn der Vektor mehr Speicher neu zuordnen muss.

Um die Neuverteilung der Speicher zu verhindern den gesamten Speicher Sie mit Reserve benötigen vorbelegt() (vorausgesetzt, Sie kennen diese Größe, wenn Sie den Vektor zuweisen).

Die einfachere Lösung hält einen indirekten Bezug auf das Element (ein Index in dem Array).

1

Wenn Sie unbedingt Iteratoren für diesen Einsatz:

std::vector<Object*> objects; 
std::vector<Object*> newObjects; 
std::vector<Object*>::iterator iter; 
for (iter = objects.begin(); iter != objects.end(); ++iter) 
{ 
    if (condition) 
    { 
     newObjects.push_back(new Object()); 
    } 
} 

std::copy(newObjects.begin(), newObjects.end(), back_inserter<vector<Object*> >(objects)); 
0

§23.1/11:

Sofern nicht anders angegeben (entweder explizit oder durch eine Funktion in Bezug auf die anderen Funktionen zu definieren) wird eine Behälterelement-Funktion oder Passieren einen Behälters als ein Argument an eine Bibliotheksfunktion aufruft nicht ungültig Iteratoren, oder Ändern Sie die Werte von Objekte in diesem Container.

Es ist jedoch nicht explizit angegeben, dass std :: vector :: push_back alle Iteratoren ungültig macht.

+0

Einige Tests, die ich gemacht habe, bestätigen, dass die push_back tatsächlich einen Iterator ungültig machen kann. – Oswald

+0

Der Grund ist wahrscheinlich, dass ein Vektor eine Sequenz ist und für eine Sequenz s, s.push_back (x) als insert (s.end(), x) definiert ist und std :: vector :: insert erlaubt ist Iteratoren ungültig machen. – Oswald

0

Da die meisten der anderen Antworten schon sagen, Sie zugreifen wahrscheinlich besser, den Vektor durch den Index in diesem Fall.

jedoch der Vollständigkeit halber: std::list Iteratoren haben dieses „Problem“ nicht. So ist die Verwendung von list anstelle von vector eine mögliche Lösung.

Verwandte Themen