首页  >  文章  >  后端开发  >  如何在迭代时安全地从 `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