Heim > Artikel > Backend-Entwicklung > Hier sind Artikeltitel, die Sie in Betracht ziehen können: **Ist es sicher, einen Iterator nach „std::vector::erase()“ zu verwenden, wenn das Element gelöscht wird, auf das er verweist?** Der Titel stellt eine einfache Frage und spiegelt genau den Inhalt des Artikels wider, in dem untersucht wird, ob es möglich ist, einen Iterator, der auf ein Element verweist, nach dem Löschen weiterhin zu verwenden. Hier sind einige andere Optionen: * **ICH
In der vorherigen Diskussion dieses Problems wissen wir alle, dass der Aufruf von std::vector::erase dies tun wird Nur den Iterator ungültig machen, der sich nach dem gelöschten Element befindet. Aber ist der Iterator an dieser Position nach dem Löschen eines Elements noch gültig (natürlich zeigt er nach dem Löschen nicht auf end())?
Ein Verständnis darüber, wie Vektoren implementiert werden, legt nahe, dass dieser Iterator definitiv verwendet werden kann, aber ich bin mir nicht sicher, ob dies zu undefiniertem Verhalten führt.
Als Beispiel entfernt der folgende Code alle ungeraden ganzen Zahlen aus einem Vektor. Verursacht dieser Code undefiniertes Verhalten?
<code class="cpp">typedef std::vector<int> vectype; vectype vec; for (int i = 0; i < 100; ++i) vec.push_back(i); vectype::iterator it = vec.begin(); while (it != vec.end()) { if (*it % 2 == 1) vec.erase(it); else ++it; }</code>
Der Code läuft auf meinem Rechner einwandfrei, aber das überzeugt mich nicht von seiner Gültigkeit.
Nicht; alle Iteratoren bei oder nach dem zum Löschen übergebenen Iterator werden ungültig.
Erase gibt jedoch einen neuen Iterator zurück, der auf das Element nach dem gelöschten Element zeigt (oder auf das Ende, wenn es kein solches Element gibt). Mit diesem Iterator können Sie die Iteration fortsetzen.
Beachten Sie, dass diese Methode zum Entfernen ungerader Elemente sehr ineffizient ist: Jedes Mal, wenn ein Element entfernt wird, müssen alle Elemente danach im Vektor um eine Position nach links verschoben werden (das ist O(n2). )). Mit dem Erase-Remove-Idiom können Sie diese Aufgabe effizienter (O(n)) erledigen. Sie können ein is_odd-Prädikat erstellen:
<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; }</code>
Anschließend können Sie es an remove_if übergeben:
<code class="cpp">vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());</code>
Das obige ist der detaillierte Inhalt vonHier sind Artikeltitel, die Sie in Betracht ziehen können: **Ist es sicher, einen Iterator nach „std::vector::erase()“ zu verwenden, wenn das Element gelöscht wird, auf das er verweist?** Der Titel stellt eine einfache Frage und spiegelt genau den Inhalt des Artikels wider, in dem untersucht wird, ob es möglich ist, einen Iterator, der auf ein Element verweist, nach dem Löschen weiterhin zu verwenden. Hier sind einige andere Optionen: * **ICH. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!