我正在研究一些基本上做的代码:
mapSize = map.size();
for(iter=map.begin;iter!=map.end();)
{
call function which might delete a map item;
if(map.size()==mapSize )
{
iter++;
}
else
{
mapSize = map.size();
iter=map.begin(); /* Start again if something was deleted */
}
}
我认为必须有更好的方法来做到这一点。有什么建议吗?
答案 0 :(得分:6)
该函数应该为您返回下一个有效的迭代器。这就是map
正常erase
函数的工作方式。
答案 1 :(得分:2)
Map具有以下重要特性:将新元素插入到映射中不会使指向现有元素的迭代器无效。从地图中删除元素也不会使任何迭代器无效,当然,除了实际指向正在被删除的元素的迭代器之外。
修改
忘了示例
for(iter=map.begin;iter!=map.end();)
{
map< type >::iterator itCopy( iter++ );
// call function which might delete a map item;
foo( itCopy );
}
答案 2 :(得分:0)
最好的方法是
这样清理工作将自动完成。
答案 3 :(得分:0)
首先调用map.size()可能会花费很多,所以不要使用太多。
for(iter=map.begin;iter!=map.end();)
{
current_iter = iter;
++iter;
// call function which might delete a map item;
my_function(current_iter);
}
答案 4 :(得分:0)
我对您的代码有一点考虑。如果你以功能的方式看待它,我认为你应该重写它不要使用实际的循环,但是,也许,像remove_if
这样的算法函数,执行多次你需要处理/删除所有的需要的元素。我认为这会导致更清晰的代码,而不必处理for循环的显式初始化。例如,在纯C ++中(不是lambda,而不是C ++ 0x,这会使这更容易):
template <typename I>
class Processor
{
bool operator(I const& i)
{ // process, return true if it has to be removed
}
};
然后,在您的代码中:
std::remove_if(map.begin(), map.end(), Processor<Item_type>());
并且在没有删除任何元素时会发现某种标记,因此您可以继续(可能是Processor
类的元素)。
答案 5 :(得分:0)
我不太确定问题是什么:标题说的是“地图” 映射“,但我在示例代码中没有看到任何内容。
除此之外:如果项目被删除,应该怎么办? 功能?是否要从头开始重新启动迭代,或者 继续你离开的地方(知道你离开的地方可能有 已从地图中删除)?首先,你的代码基本上是 是的,我不认为有更好的解决方案;至少我 想不到一个人。第二,我想你想要的 类似的东西:
iter = map.begin();
while ( iter != map.end() ) {
key = iter->first;
// call function...
iter = map.upper_bound( key );
}
这可能是最简单的解决方案。 map.upper_bound
是O(lg n)
,
然而;如果地图很大,这可能是个问题。取决于
map
的实现(以及您的功能的频率
删除元素),如果没有,则在迭代器上使用++
从地图中删除可能会更快。
当然,如果你能保证有问题的功能永远不会
在您所在的元素之后删除该元素,您可以增加该元素
调用函数之前的迭代器。 upper_bound
的解决方案,
然而,无论功能如何变化,都无条件地工作
在地图上。
答案 6 :(得分:-1)
要知道的一件好事是,前缀运算符++
返回迭代器的先前值(副本),并将当前迭代器碰撞到下一个值。所以下一个代码在你的情况下非常有趣:
for (iter = map.begin(); iter != map.end(); )
{
// call function which might delete the item
your_function(++iter);
// and... that's all !
}
这样,如果你通过erase
falvor在参数中取一个迭代器来删除你的函数,你的当前迭代器就不会被删除了。