开发者社区> 问答> 正文

C++ STL 遍历 map 的时候如何删除其中的 element - C++报错

"

我们通过map的erase(iterator it)方法删除元素的时候,如果此时erase处于遍历map的代码中,那么调用erase就需要小心一些。因为erase会导致输入参数iterator变的无效,从而影响后续的it++遍历map的逻辑。

简单做法是,先将要删除的it保存下来,然后将用于遍历map的it指向下一个位置,然后删除掉保存下来的it。如下面代码所示:

#include <map>
#include <iostream>
using namespace std;

int main()
{
    map<int, int> map1;
    map<int, int>::iterator mapit;
    map<int, int>::iterator saveit;

    map1[1] = 2;
    map1[2] = 3;
    map1[3] = 4;
    map1[4] = 5;

    mapit = map1.begin();
    while (mapit != map1.end()) {
        cout << "Element key: " << mapit->first << ", value: " << mapit->second << endl;
        if (mapit->first == 2) {
            saveit = mapit;
            mapit++;
            map1.erase(saveit);
            continue;
        }
        mapit++;
    }

    cout << "Map size: " << map1.size() << endl;
    return 0;
}

需要注意的是,这里windows的STL(windows C++编译器带的STL)和linux上的STL(gcc的STL)实现不同。

windows 的STL中,map的erase方法会返回一个iterator,这个iterator指向的是当前被删除的iterator后面的iterator,所以这样的话,只需要将用于循环的iterator赋成erase函数的返回值就可以了。参考上面代码,就是这样:

mapit = map1.erase(mapit);然后continue就可以。

但是Linux下这样写代码是无法通过编译的。

文章出处:http://www.cnblogs.com/super119/archive/2011/10/11/2207541.html

"

展开
收起
montos 2020-06-03 13:06:25 1195 0
1 条回答
写回答
取消 提交回答
  • "<pre class=""brush:cpp; toolbar: true; auto-links: false;"">typedef std::map<int,int> MapType;

    MapType _map; for(MapType::iterator iter = _map.begin(); iter != _map.end(); ++iter) { if(true) //条件自己去写 _map.erase(iter++); else iter++; }

    ######有问题,循环一次item就自增了两次. for(MapType::iterator iter = _map.begin(); iter != _map.end(); ++iter) ----> for(MapType::iterator iter = _map.begin(); iter != _map.end();)######这里有错误,并没有完全每个项都检查是否满足条件,应该把for(;;++iter)去掉。######恩,for里面那个自增要去掉."
    2020-06-03 13:41:05
    赞同 展开评论 打赏
问答分类:
C++
问答地址:
问答排行榜
最热
最新

相关电子书

更多
使用C++11开发PHP7扩展 立即下载
GPON Class C++ SFP O;T Transce 立即下载
GPON Class C++ SFP OLT Transce 立即下载