C++ 中经常使用的容器类有vector,list,map。其中vector和list的erase都是返回迭代器,但是map就比较不一样。

当在循环体中使用map::erase语句时,为了能够在任何机器上编译通过,并且能够跨平台(windows、linux),正确的写法是:

map<int, int> l_map;
map<int, int>::iterator l_iter = l_map.begin();
map<int, int>::iterator l_iterErase;
while (l_iter != l_map.end())
{
l_iterErase = l_iter;
l_iter++;
l_map.erase(l_iterErase);
}

也有人提出了这样的写法:

map<int, int> l_map;
map<int, int>::iterator l_iter = l_map.begin();
while (l_iter != l_map.end())
{
l_map.erase(l_iter++);
}

这个写法据某牛人说,只适合参数入栈顺序是从右向左的方式,参数入栈顺序是和具体编译器实现相关的。也就是,如果不幸遇到参数入栈顺序是从左向右的,上面的写法就不行了。


上面是牛人的说法,但是我想不通的是,只有一个参数的时候,参数入栈顺序应该没有影响啊?
关于函数参数中带++,--运算符的文章请见: i++和++i作为参数时的编译器处理方式分析~


正确使用stl map的erase方法

先声明:下面的文章是针对windows的用法,因为std::map的erase函数的windows的实现版本是返回一个std::map的迭代器,但是STL标准里面的该函数的返回值确是:

map.erase有3个重载,不同的C++版本标准其erase函数也不同:

  1. C++98(1998/2003 Standard)
void erase (iterator position);
size_type erase (const key_type& k);
void erase (iterator first, iterator last);
  1. C++11(2011 Standard)
iterator  erase (const_iterator position);
size_type erase (const key_type& k);
iterator erase (const_iterator first, const_iterator last);

所以下面的代码中的最后一个例子仅仅可以在windows下的map下运行。

STL的map表里有一个erase方法用来从一个map中删除掉指令的节点
eg1:

map<string,string> mapTest;
typedef map<string,string>::iterator ITER;
ITER iter=mapTest.find(key);
mapTest.erase(iter);

像上面这样只是删除单个节点,map的形为不会出现任务问题,但是当在一个循环里用的时候,往往会被误用,那是因为使用者没有正确理解iterator的概念.
像下面这样的一个例子就是错误的写法,
eg2:

for(ITER iter=mapTest.begin();iter!=mapTest.end();++iter)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter);
}

这是一种错误的写法,会导致程序行为不可知.究其原因是map 是关联容器,对于关联容器来说,如果某一个元素已经被删除,那么其对应的迭代器就失效了,不应该再被使用;否则会导致程序无定义的行为。
可以用以下方法解决这问题:
正确的写法
1.使用删除之前的迭代器定位下一个元素。STL建议的使用方式

for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
mapTest.erase(iter++);
}

2. erase() 成员函数返回下一个元素的迭代器

for(ITER iter=mapTest.begin();iter!=mapTest.end();)
{
cout<<iter->first<<":"<<iter->second<<endl;
iter=mapTest.erase(iter);
}

关于map::erase的使用说明的更多相关文章

  1. map::erase陷阱

    map::erase函数在不同版本stl中的差异 1. C++98和C++11标准 http://www.cplusplus.com/reference/map/map/erase/ 2. pj st ...

  2. [转] C++ STL中map.erase(it++)用法原理解析

    总结一下map::erase的正确用法. 首先看一下在循环中使用vector::erase时我习惯的用法: for(vector<int>::iterator it = vecInt.be ...

  3. vector.erase();vector.clear();map.erase();

    vector::erase()返回下一个iter: STL中的源码: //清除[first, last)中的所有元素 iterator erase(iterator first, iterator l ...

  4. map erase iterator

    错误写法: map<int, int> m; for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) ...

  5. C++ std::map::erase用法及其陷阱

    1.引入: STL的map中有一个erase方法用来从一个map中删除制定的节点 eg: map<string,string> mapTest; typedef map<string ...

  6. map 和 vector 的erase函数说明

    1. map的erase函数使用 这里首先要注意,C++针对map的erase函数有不同的函数原型,这往往是出现问题的关键所在.根据参考文献1: 在C++98中: (1) void erase (it ...

  7. 正确使用stl map的erase方法

    先声明:下面的文章是针对windows的用法,因为std::map的erase函数的windows的实现版本是返回一个std::map的迭代器,但是STL标准里面的该函数的返回值确是: map.era ...

  8. map/vector erase

    问题核心:erase之后迭代器是否失效 vector调用erase之后,该迭代器之后的迭代器都失效: map调用erase之后,其他迭代器并不会失效. vector<int> vecDat ...

  9. C++ map 使用erase在windows下崩溃,在linux下没有问题的原因

    注意:此程序在win环境下会出现上述描述的问题:在mac环境下第一种方式是正常运行的.Map.erase有3个重载函数: void erase(iterator position); size_typ ...

随机推荐

  1. Python模块和类.md

    模块的定义 代码的层次结构 对于python的层次结构一般为包->模块 包也就是文件夹,但是文件夹下必须有文件"init.py"那么此文件夹才可以被识别为包."in ...

  2. Oracle 未能加载文件或程序集Oracle.DataAccess

    原文地址;https://www.cnblogs.com/xuekai-to-sharp/p/3586071.html 关键是引用DLL:Oracle.DataAccess.dll DLL文件的路径: ...

  3. C++读取txt和保存到txt

    哇,今天又重新用C++来写了一些代码发现自己竟然在类的使用和文件读取和保存上面特别头疼,于是,各种问度娘+各种翻看之前的代码.不禁感叹,自己的代码还是写的太少了,对这些一点都不熟悉.于是,今晚!一定! ...

  4. 如何使用CBO,CBO与RULE的区别

    Oracle的优化器有两种优化方式,即基于规则的优化方式(Rule-Based Optimization,简称为RBO)和基于代价的优化方式(Cost-Based Optimization,简称为CB ...

  5. vue 高级属性父组件provide向子组件发送数据,子组件通过inject接收数据

    以前父组件向子组件中传值是通过props传值,子组件不能更改父组件中的值,但是可以通过从父组件中获取的值定义给自己的data值,这里父组件可以通过provide向子组件传递自己组件中的data值,子组 ...

  6. java第一课总结

    转眼间开学了,我们也正式进入了大二.心里既有激动,又有些感慨,还带有一些担忧.激动的是我们褪去了大一的稚气成为了一名大二的学长了,第一次体会到了大学学长的感觉,心里很是激动.感慨的是我们又成长了一岁, ...

  7. SpringBoot @Async注解失效分析

    有时候在使用的过程中@Async注解会失效(原因和@Transactional注解有时候会失效的原因一样). 下面定义一个Service: 两个异步执行的方法test03()和test02()用来模拟 ...

  8. JMeter学习(二十八)内存溢出解决方法(转载)

    转载自 http://www.cnblogs.com/yangxia-test 使用jmeter进行压力测试时遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jme ...

  9. html自定义弹框

    一.要实现的功能 1.弹框弹出时有遮罩 2.弹框内的文字过多时右侧有滚动条 3.根据执行结果变更弹框title的样式   二.具体实现 思路:定义一个有宽高的div,默认隐藏,当要显示时,设置为dis ...

  10. date命令转换日期命令提示date: illegal time format

    问题:运行date命令抛错 date -j -f "%a %b %d %T %Z %Y" "Sat Sep 29 11:33:00 CST 2018" &quo ...