2012-03-12 101 views
2

好吧,我已经遇到过这个问题多次,并认为这将是很好的把这个扔在SO上的好人。从容器中删除元素时,通过它们迭代

说我已经做了一个类,让我们称之为资源。 因此,Resource类有一个布尔变量,它指示任何实例处于活动状态的天气。

现在,我创建了一个容器来保存对资源类型对象的引用。

随着时间的推移,其中一些被取消激活,我想删除这些停用的对象,以便释放内存。 总是我试着做到这一点:尝试迭代容器中的元素并删除标记为非活动状态的元素。这显然会导致迭代器失效的问题,并且程序开始抛出运行时错误。

因此,最后,我的问题是,根据某些只能通过查看对象的内容才能评估的条件来安全删除对象的最佳方法是什么。

+1

[迭代时删除]的​​可能重复(http://stackoverflow.com/questions/3901356/deleting-while-iterating) – 2012-03-12 11:53:33

+0

可能重复[迭代向量,删除某些项目,我去](http:// stackoverflow.com/questions/1604588/iterate-vector-remove-certain-items-as-i-go) – 2012-03-12 12:26:26

+0

不只是讨论向量或列表,还有地图和其他关联容器。 – angryInsomniac 2012-03-13 06:27:20

回答

4

使用erase-remove idiomstd::remove_if。例如:

std::vector<int> myvec; 
... 
myvec.erase(std::remove_if(myvec.begin(),myvec.end(), [] (int i) -> bool { return false; }), myvec.end()); 
+0

关于像地图这样的关联容器怎么样? std :: remove_if不为他们工作,我收集。 – angryInsomniac 2012-03-13 06:25:16

+0

@angryInsomniac:不,它不起作用,因为它会破坏排序。 [这个问题](http://stackoverflow.com/questions/9515357/map-lambda-remove-if)为这个问题提供了一个答案。 – KillianDS 2012-03-13 07:30:15

0

最安全的方法是使用std::remove_if。这会将与给定谓词匹配的所有项目移动到序列的末尾。你可以删除它们。

+0

关于像地图这样的关联容器怎么样? – angryInsomniac 2012-03-13 06:24:47

+0

通过映射,您可以删除迭代器指向的元素,而不会使任何其他迭代器失效。这意味着你可以做'your_map.erase(it ++);'。请参阅[此问题](http://stackoverflow.com/questions/6438086/)以获取更多信息。 – 2012-03-13 07:28:04