免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7829 | 回复: 11
打印 上一主题 下一主题

[C++] 关于map的erase使用 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-03-19 16:40 |只看该作者 |正序浏览
说明:data.erase(it++); 语句执行后,it可以指向被删除元素之后的元素。

问题:
1)data.erase(it++); 这个语句执行的原理是什么?
2) 为什么data.erase(it++); 这个语句 和 {data.erase(it);  it++}执行效果不同?
  1. int main() {
  2.   map<int, int> data;
  3.   data.insert(make_pair(1,1));
  4.   data.insert(make_pair(2,2));
  5.   data.insert(make_pair(3,2));
  6.   data.insert(make_pair(4,3));
  7.   for (map<int, int>::iterator it = data.begin();
  8.       it != data.end();) {
  9.     if (it->second == 2) {
  10.       cout << it->first << ": " << it->second << endl;
  11.       data.erase(it++);
  12.     } else {
  13.       ++it;
  14.     }   
  15.   }
  16.   cout << "final:"<< endl;
  17.   for (map<int, int>::iterator it = data.begin();
  18.       it != data.end(); ++it) {
  19.     cout << it->first << ": " << it->second << endl;
  20.   }
  21.   return 0;
  22. }
复制代码

论坛徽章:
0
12 [报告]
发表于 2013-03-19 21:01 |只看该作者
本帖最后由 millionfee 于 2013-03-19 21:02 编辑

data.erase(it++);

it的++操作符会将自增前自身的一个副本返回供erase()使用,
并且在erase()执行前已经指向了下一个元素。

map的erase()操作会使it的副本(那个指向被删除元素的迭代器)失效,其他迭代器不受影响。
所以自增后的it仍可用与循环判断。

论坛徽章:
4
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT运维版块每日发帖之星
日期:2016-08-11 06:20:00IT运维版块每日发帖之星
日期:2016-08-15 06:20:00
11 [报告]
发表于 2013-03-19 18:31 |只看该作者
恩,果然如此!
看来必须用:
data.erase(it++);

论坛徽章:
0
10 [报告]
发表于 2013-03-19 17:47 |只看该作者
回复 8# happy_fish100


  多加几个数据,测试一下,结果就不对了。比如:

  data.insert(make_pair(1,1));
  data.insert(make_pair(2,2));
  data.insert(make_pair(3,2));
  data.insert(make_pair(4,3));
  data.insert(make_pair(5,2));
  data.insert(make_pair(6,6));


  你试一下。

论坛徽章:
0
9 [报告]
发表于 2013-03-19 17:40 |只看该作者
回复 8# happy_fish100


  erase(it); 之后,it这个迭代器失效,任何使用it的操作后果都是未定义的。

  可能你测试的时候刚好可以幸运地得到正确的结果,但也只能说明运气好而已。

论坛徽章:
4
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT运维版块每日发帖之星
日期:2016-08-11 06:20:00IT运维版块每日发帖之星
日期:2016-08-15 06:20:00
8 [报告]
发表于 2013-03-19 17:34 |只看该作者
回复 7# silentfly1987

为什么绝对不可以?测试过么?

论坛徽章:
0
7 [报告]
发表于 2013-03-19 17:31 |只看该作者
happy_fish100 发表于 2013-03-19 17:12
我测试过了,效果一样的啊!

你可以把循环语句改为:


这样是绝对不可以的

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
6 [报告]
发表于 2013-03-19 17:23 |只看该作者
happy_fish100 发表于 2013-03-19 17:12
我测试过了,效果一样的啊!

你可以把循环语句改为:


你这个不保险

论坛徽章:
4
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT运维版块每日发帖之星
日期:2016-08-11 06:20:00IT运维版块每日发帖之星
日期:2016-08-15 06:20:00
5 [报告]
发表于 2013-03-19 17:12 |只看该作者
我测试过了,效果一样的啊!

你可以把循环语句改为:
for (map<int, int>::iterator it = data.begin();  it != data.end(); it++)
然后循环体中就不用it++或者++it了!
效果都一样!

论坛徽章:
0
4 [报告]
发表于 2013-03-19 17:04 |只看该作者
回复 3# happy_fish100

执行效果是不同
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP