C++ 在循环中不间断地从列表中删除元素

C++ 在循环中不间断地从列表中删除元素,c++,C++,在我的游戏代码中,我想从列表中删除一些元素 这在循环中发生。我唯一的问题是,当我使用 list::erase我必须在该函数之后中断,因为我认为 列表变得“过时”。这会引起一点闪烁,我想 尝试移除它 当前代码如下: for(list<Arrow*>::iterator it = arrows.begin(); it != arrows.end(); it++) { Arrow* a = (*it); if(a->isActive() == true) {

在我的游戏代码中,我想从
列表中删除一些元素
这在循环中发生。我唯一的问题是,当我使用
list::erase
我必须在该函数之后中断,因为我认为
列表
变得“过时”。这会引起一点闪烁,我想
尝试移除它

当前代码如下:

for(list<Arrow*>::iterator it = arrows.begin(); it != arrows.end(); it++)
{
    Arrow* a = (*it);

    if(a->isActive() == true)
    {
        a->update();
    }
    else
    {
        arrows.erase(it);
        break;
    }
}
for(list::iterator it=arrows.begin();it!=arrows.end();it++)
{
箭头*a=(*it);
如果(a->isActive()==true)
{
a->update();
}
其他的
{
箭头。擦除(它);
打破
}
}
提前谢谢你

编辑: 对不起,我被向量和列表弄糊涂了。知道答案了,谢谢

你应该做:

it = arrows.erase(it);
//

list::iterator it=arrows.begin();
while(it!=arrows.end())
{
箭头*a=(*it);
如果(a->isActive())
{
a->update();++it;
}
否则{//删除(a)???
它=箭头。擦除(它);}
}
您应该执行以下操作:

it = arrows.erase(it);
//

list::iterator it=arrows.begin();
while(it!=arrows.end())
{
箭头*a=(*it);
如果(a->isActive())
{
a->update();++it;
}
否则{//删除(a)???
它=箭头。擦除(它);}
}

我很困惑,你说的是向量,而在你的例子中你使用的是列表

列表是用一个双链接列表实现的(实际上它很可能被实现,因为标准只修复了复杂性而不是细节)。擦除后的迭代器仍然有效


中间用向量擦除是慢的,也使所有迭代器和引用无效。

我很困惑,你说向量,在你的例子中,你使用的是列表。

列表是用一个双链接列表实现的(实际上它很可能被实现,因为标准只修复了复杂性而不是细节)。擦除后的迭代器仍然有效


中间用向量擦除是慢的,也使所有迭代器和引用无效。

< P>标准库容器中筛选项目的正确方法是使用。因为您使用的是成员函数作为循环中的测试,所以应该调整示例以使用它

您可以用一种简短的方式(如果您喜欢函数式编程)实现这一点:

#包括
#包括
箭头。删除(标准::删除(
arrows.begin()、arrows.end()、std::mem_-fun(&Arrow::isActive)
));
这将适用于
std::vector
std::deque
std::list
等,而不考虑实现和迭代器无效语义

Edit:我看到您还在循环中使用
Arrow::update()
方法。您可以对列表进行双传递,使用函数对象调用这两个方法,或者手动编写循环

在最后一种情况下,您可以使用
it=arrows.erase(它)技巧,但这只对
std::list
有效。循环的复杂性为
O(n^2)

std::vector
std::deque
容器。

筛选标准库容器中项目的正确方法是使用。因为您使用的是成员函数作为循环中的测试,所以应该调整示例以使用它

您可以用一种简短的方式(如果您喜欢函数式编程)实现这一点:

#包括
#包括
箭头。删除(标准::删除(
arrows.begin()、arrows.end()、std::mem_-fun(&Arrow::isActive)
));
这将适用于
std::vector
std::deque
std::list
等,而不考虑实现和迭代器无效语义

Edit:我看到您还在循环中使用
Arrow::update()
方法。您可以对列表进行双传递,使用函数对象调用这两个方法,或者手动编写循环

在最后一种情况下,您可以使用
it=arrows.erase(它)技巧,但这只对
std::list
有效。循环的复杂性为
O(n^2)

std::vector
std::deque
容器。

就像大家说的那样,您的示例令人困惑。如果要在容器中间删除,并且使用

1> 向量: 然后,擦除点之后的每个迭代器和引用都无效。 另外,从向量的中间删除向量会导致后面的元素移动,如果您想要性能,这可能会被认为是缓慢的

2> 名单: 然后,只有删除的迭代器和引用无效


当你想删除STL序列容器中间的某个元素时,最好使用任一种方法。

< P>就像每个人都说你的例子是混乱的。如果要在容器中间删除,并且使用

1> 向量: 然后,擦除点之后的每个迭代器和引用都无效。 另外,从向量的中间删除向量会导致后面的元素移动,如果您想要性能,这可能会被认为是缓慢的

2> 名单: 然后,只有删除的迭代器和引用无效


在STL序列容器的中间部分删除某个元素时,使用任一个首选项。

是<代码> STD::vector < /代码>还是<代码> STD::列表< /代码>?如果是
列表
,请编辑您的问题和标题。抱歉,请立即编辑。谢谢你的留言!这是一个
std::vector
还是一个
std::list
?如果是
列表
,请编辑您的问题和标题。抱歉,请立即编辑。谢谢你的留言!谢谢,这就是答案。我先处理向量,但我忘了我改成了列表。这解决了问题,谢谢!我觉得最好用“而不是”来表示“@Benjamin:对不起,你说得对。我习惯于将
arrows.end()
赋值给局部变量。执行此操作时,调用
erase()
会使结束迭代器无效。
#include <algorithm>
#include <functional>

arrows.erase(std::remove_if(
    arrows.begin(), arrows.end(), std::mem_fun(&Arrow::isActive)
    ));