3

可能重复:
如何从 std::map 中过滤项目?
如果在从头到尾迭代时在地图元素上调用 erase() 会发生什么?

我有对象图,我想遍历它并删除一些条目。

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

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

我可以这样做吗?

4

2 回答 2

8

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

你需要使用:

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

请注意,此处it++递增it,以便它引用下一个元素但产生其原始值的副本。因此,it不指erase()调用时删除的元素。

于 2012-05-09T17:08:19.353 回答
2

假设MapT为 a std::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;
    } 
}
于 2012-05-09T17:10:49.290 回答