Heim  >  Artikel  >  Backend-Entwicklung  >  Wie entferne ich während der Iteration sicher Elemente aus einem „std::vector“?

Wie entferne ich während der Iteration sicher Elemente aus einem „std::vector“?

DDD
DDDOriginal
2024-11-01 20:27:02169Durchsuche

How to Safely Remove Elements from a `std::vector` While Iterating?

Iterieren und Löschen aus std::vector

Der empfohlene Ansatz für die Iteration durch einen std::vector ist die Verwendung von Iteratoren. Das Löschen von Elementen während der Iteration kann jedoch dazu führen, dass der Iterator ungültig wird.

Um dieses Problem zu beheben, ist es wichtig, die Iteratorzuweisung nach dem Löschen eines Elements zu ändern, wie unten gezeigt:

<code class="cpp">for (iterator it = begin; it != end(container) /* !!! */; )
{
    if (it->somecondition())
    {
        it = vec.erase(it);  // Returns the new iterator to continue from.
    }
    else
    {
        ++it;
    }
}</code>

Es ist wichtig, Folgendes zu tun Beachten Sie, dass das Ende des Containers jedes Mal neu berechnet werden sollte, nachdem ein Element gelöscht wurde.

Eine effizientere Alternative ist die Kombination von std::remove_if und erase():

<code class="cpp">iterator it = std::remove_if(begin, end, pred);
vec.erase(it, vec.end());</code>

Dieser Ansatz ändert die Zeitkomplexität von O(N^2) auf O(N). Hier ist ein Beispiel für ein Prädikat zum Entfernen von Elementen:

<code class="cpp">struct predicate
{
    bool operator()(const T& pX) const
    {
        return pX.shouldIBeRemoved();
    }
};</code>

Für Ihren speziellen Fall können Sie einen allgemeineren Ansatz verwenden:

<code class="cpp">class remove_by_caller
{
public:
    remove_by_caller(AguiWidgetBase* pWidget) : mWidget(pWidget) {}
    template <typename T>
    bool operator()(const T& pX) const
    {
        return pX.getCaller() == mWidget;
    }
private:
    AguiWidgetBase* mWidget;
};</code>

Verwenden Sie diesen Ansatz:

<code class="cpp">std::vector<AguiTimedEvent>::iterator it =
    std::remove_if(timedEvents.begin(), timedEvents.end(), remove_by_caller(widget));
timedEvents.erase(it, timedEvents.end());</code>

Darüber hinaus können Lambda-Ausdrücke diesen Prozess vereinfachen, wie sie sowohl in Boost als auch in C 11 unterstützt werden.

Das obige ist der detaillierte Inhalt vonWie entferne ich während der Iteration sicher Elemente aus einem „std::vector“?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn