迭代通过STL容器和删除/添加多个项目 [英] Iterating through STL containers and removing/adding multiple items

查看:98
本文介绍了迭代通过STL容器和删除/添加多个项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中发生的最常见的错误之一是,STL容器在循环期间被修改。

One of the most frequent errors that occur in my code is that STL containers are modified during a loop.

元素在循环执行期间被删除或添加,所以我通常会遇到超出范围的异常。

Elements are removed or added during a loop execution so I usually run into out of bounds exceptions.

for循环通常看起来像这样:

My for loops usually looks like this:

for (auto& Item : Items) { // Will not work when Items container is modified
    //... loop logic
}

已删除,我使用此怪物:

When multiple items can be removed, I use this monstrosity:

for (int Index=Items.size()-1;Index<=0;Index--) {
    if (Index<Items.size()) { //Because multiple items can be removed in a single loop
        //... loop logic
    }
}

这看起来不好,让我觉得不好用第二个选项。多个项目可以删除的原因是由于事件,其中单个事件可以删除任何数量的元素。

This looks bad and it makes me feel bad using that second option. The reason multiple items can be removed is due to events, where a single event can remove any number of elements.

这里是一些伪代码来说明发生这种情况时: / p>

Here is some pseudo code to illustrate when this occurs:

// for each button in vector<button> {
// process button events
// event adds more buttons to vector<button>
// *ERROR* vector<button> is modified during loop.
// }



在另一个例子中,设想一个包含以下项目的向量:

In another example, imagine a vector with following items:

// 0 1 2 3 4 5 6 7 8 9

我们从 0 开始循环并逐个元素。在 4 ,我要删除 1 4 9 ,因此我们不能在这里使用正常循环。

We start our loop at 0 and go element by element. At 4, I want to remove elements 1,4 and 9 so we can't use a normal loop here.

推荐答案

使用 std :: remove_if 和决定是否需要删除按钮的谓词:

Use std::remove_if with a predicate that decide if a button needs to be removed:

bool needsRemoved(const Button& button);

vec.erase(std::remove_if(vec.begin(), vec.end(), &needsRemoved), vec.end());

EDIT :对于最后一个例子, )算法是:

EDIT: For your last example, the quadratic (i.e. bad for performance) algorithm is:

std::vector<int> vec = {0,1,2,3,4,5,6,7,8,9};
auto end = vec.end();
for (auto it = vec.begin(); it < end; ++it)
{
    std::set<int> bad = {1, 4, 9};
    end = std::remove_if
        (vec.begin(), end,
         [bad](int x) { return (bad.find(x) != bad.end()); });
}
vec.erase(end, vec.end());

你可能会更好地使用一个快速查找的容器)。

You will probably be better off using a container with fast lookup though (like a set, or a map).

这篇关于迭代通过STL容器和删除/添加多个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆