在我的游戏代码中,我想从list
中删除一些元素
这发生在一个循环中。我唯一的问题是,当我使用
时
list::erase
因为我认为,我必须在这个功能之后休息
list
变得“过时”。这会导致一点点闪烁,我想要
试着删除它。
目前的代码是:
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;
}
}
提前谢谢!
编辑: 对不起,我对矢量和列表很困惑。得到了答案,谢谢!
答案 0 :(得分:8)
你应该这样做:
it = arrows.erase(it);
//
list<Arrow*>::iterator it = arrows.begin();
while (it != arrows.end())
{
Arrow* a = (*it);
if(a->isActive())
{
a->update(); ++it;
}
else{ // delete (a); ???
it=arrows.erase(it);}
}
答案 1 :(得分:0)
我很困惑,你说矢量,在你的例子中你使用的是列表。
列表是用双链表实现的(实际上很可能会实现,因为标准只修复了复杂性而不是细节)。擦除后的迭代器仍然有效。 http://www.cplusplus.com/reference/stl/list/erase/
使用向量在中间擦除速度很慢,并且还使所有迭代器和引用无效。
答案 2 :(得分:0)
过滤掉标准库容器中的项目的正确方法是使用Erase-Remove Idiom。因为您在循环中使用成员函数作为测试,所以您应该调整示例以使用std::remove_if()
。
你可以用简短的方式实现这一点(假设你喜欢函数式编程):
#include <algorithm>
#include <functional>
arrows.erase(std::remove_if(
arrows.begin(), arrows.end(), std::mem_fun(&Arrow::isActive)
));
这适用于std::vector<>
,std::deque<>
,std::list<>
等,无论实现和迭代器失效语义如何。
修改:我发现你在循环中也使用了Arrow::update()
方法。您可以在列表上执行双遍,使用函数对象来调用这两个方法或手动编写循环。
在最后一种情况下,您可以使用it = arrows.erase(it);
技巧,但这只会对std::list<>
有效。该循环将具有O(n^2)
复杂度
std::vector<>
和std::deque<>
容器。
答案 3 :(得分:0)
就像所有人都说你的例子令人困惑。如果要在容器中间删除,并且使用
1&GT;矢量: 然后擦除点之后的每个迭代器和引用都无效。 另外,从向量中间删除向量将导致其后面的元素移位,如果你想要性能,可能会认为它很慢。
2 - ;列表: 然后只有删除的迭代器和引用无效。
当您想删除stl序列容器中间的某个元素时,首选使用erase-remove idiom。