当我从地图中删除条目时,`map :: iterator`会发生什么?

时间:2012-05-09 17:04:55

标签: c++ map iterator

  

可能重复:
  How to filter items from a std::map?
  What happens if you call erase() on a map element while iterating from begin to end?

我有对象的地图,我想迭代它并删除一些条目。

typedef std::map<A,B> MapT;
MapT m;
MapT::iterator it;

for(it = m.begin(); it != m.end(); it++ ) {
    if( condition ) m.erase(it);
}

我可以这样做吗?

2 个答案:

答案 0 :(得分:8)

如果std::map迭代器和对已擦除元素的引用无效[23.1.2 / 8]。您的代码在失效后使用迭代器,这会导致未定义的行为。为了避免这种未定义的行为,迭代器需要在在<{1}}调用中失效之前递增

您需要使用:

erase()

请注意,此处for(it = m.begin(); it != m.end(); ) { if( condition ) m.erase(it++); else ++it; } 会增加it++,以便它引用下一个元素,但会生成其原始值的副本。因此,it不会引用在调用it时删除的元素。

答案 1 :(得分:2)

假设MapTstd::map,则删除后迭代器将失效。执行此操作的正确方法(循环中的erase)是在擦除之前缓存迭代器和增量:

MapT m;
MapT::iterator it;

for(it = m.begin(); it != m.end();)
{
    if(condition)
    {
       MapT::iterator tmp = it++;
       m.erase(tmp);
    }
    else
    {
       ++it;
    } 
}