【问题标题】:What happens with `map::iterator` when i remove entry from map? [duplicate]当我从地图中删除条目时,`map::iterator` 会发生什么? [复制]
【发布时间】:2012-05-18 05:51:34
【问题描述】:

可能重复:
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);
}

这样可以吗?

【问题讨论】:

  • 一旦修改地图,迭代器将失效。
  • here。 (重复)

标签: c++ map iterator


【解决方案1】:

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

你需要使用:

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

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

【讨论】:

    【解决方案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;
        } 
    }
    

    【讨论】:

      猜你喜欢
      • 2017-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多