Heim >Backend-Entwicklung >C++ >## Ist der Iterator an der gelöschten Position in std::vector::erase() noch gültig?
Grundlegendes zur Iterator-Invalidierung in std::vector::erase()
In dieser Diskussion befassen wir uns mit dem Thema der Iterator-Invalidierung, wenn Aufruf von std::vector::erase(). Wie aus früheren Debatten bekannt ist, ist es erwiesen, dass das Löschen eines Elements aus einem Vektor Iteratoren ungültig macht, die sich nach dem gelöschten Element befinden. Es stellt sich jedoch die Frage: Gilt der am gelöschten Element positionierte Iterator noch als gültig?
Trotz unseres intuitiven Verständnisses, dass der Iterator an der gelöschten Position verwendbar bleiben sollte, ist das genaue Verhalten nicht immer klar. Um dieses Konzept zu veranschaulichen, analysieren wir den folgenden Codeausschnitt, der alle ungeraden Ganzzahlen aus einem Vektor entfernt:
<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>
Obwohl dieser Code erfolgreich ausgeführt wird, verstößt er gegen Best Practices. Gemäß dem C-Standard macht erase() alle Iteratoren bei oder nach den als Parameter bereitgestellten Iteratoren ungültig. In diesem Fall bedeutet dies, dass der Iterator an der gelöschten Position ungültig wird.
erase() gibt jedoch praktischerweise einen neuen Iterator zurück, der auf das Element unmittelbar nach dem/den gelöschten Element(en) oder auf vec.end zeigt (), wenn kein solches Element existiert. Dieser neue Iterator kann verwendet werden, um die Iteration sicher fortzusetzen.
Es ist wichtig zu beachten, dass die oben genannte Methode zum Entfernen ungerader Elemente nicht effizient ist. Jedes Mal, wenn ein Element gelöscht wird, müssen nachfolgende Elemente im Vektor nach links verschoben werden, was zu einer O(n2)-Komplexität führt. Diese Aufgabe lässt sich mit der Erase-Remove-Sprache, die in O(n) arbeitet, effizienter lösen. Indem wir ein Prädikat wie is_odd() erstellen, können wir den Löschvorgang verfeinern:
<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; } vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());</code>
Das obige ist der detaillierte Inhalt von## Ist der Iterator an der gelöschten Position in std::vector::erase() noch gültig?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!