首頁  >  文章  >  後端開發  >  如何在迭代時安全地從 `std::vector` 中刪除元素?

如何在迭代時安全地從 `std::vector` 中刪除元素?

DDD
DDD原創
2024-11-01 20:27:02169瀏覽

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

從 std::vector 迭代和擦除

迭代 std::vector 的建議方法是使用迭代器。然而,在迭代時擦除元素可能會使迭代器失效。

要解決這個問題,在擦除元素後修改迭代器賦值至關重要,如下所示:

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

重要的是請注意,每次擦除元素後都應重新計算容器的末端。

更有效的替代方案是將std::remove_if 和Erase() 結合起來:

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

這種方法將時間複雜度從O(N^2) 更改為O (N)。以下是用於刪除元素的謂詞範例:

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

對於您的特定情況,您可以使用更通用的方法:

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

使用此方法:

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

此外,lambda 表達式可以簡化此過程,Boost 和C 11 都支援。

以上是如何在迭代時安全地從 `std::vector` 中刪除元素?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn