Home  >  Article  >  Backend Development  >  How to Safely Erase Elements from an `std::vector` While Iterating?

How to Safely Erase Elements from an `std::vector` While Iterating?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-11-02 16:23:30430browse

How to Safely Erase Elements from an `std::vector` While Iterating?

Erasing from an std::vector While Iterating

When iterating over an std::vector and attempting to erase an element based on a condition, using the v[i] method can lead to unpredictable behavior due to iterator invalidation. To address this issue effectively, it's recommended to employ the proper iteration technique using iterators.

One approach is to use the erase() method, which returns a new iterator. This allows for the continuation of the iteration without losing track of the desired elements:

<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>

Note that in this approach, we must obtain the end explicitly each time as the previous end iterator may become invalidated due to erasures.

An alternative method is to combine std::remove_if with erase():

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

This approach replaces the O(N2) time complexity of erasing elements individually with a more efficient O(N) operation. The erase() operation removes the elements that have been marked by the remove_if operation.

In your specific case, you can create a custom predicate that checks for the removal condition:

<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;
};

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

By employing these techniques, you can efficiently erase elements from an std::vector while iterating over it, without compromising the integrity of the iteration process.

The above is the detailed content of How to Safely Erase Elements from an `std::vector` While Iterating?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn