迭代地图和删除项目的最佳模式是什么?

时间:2011-06-01 12:17:46

标签: c++ stl iterator

我正在研究一些基本上做的代码:

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 */
  }
}

我认为必须有更好的方法来做到这一点。有什么建议吗?

7 个答案:

答案 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)

最好的方法是

  • 只有地图地图而不是地图指针地图
  • 在其中插入对象...或shared_ptr

这样清理工作将自动完成。

答案 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_boundO(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在参数中取一个迭代器来删除你的函数,你的当前迭代器就不会被删除了。