今天在删除vector中的元素中遇到一个问题,这里记录下来以便以后查阅。

预备知识:用到了erase()函数,对于一个容器c来说,假设迭代器为p,那么执行:

c.erase(p)之后就删除了容器c中p所指向的元素,并且返回一个迭代器,返回的迭代器指向刚才所删除元素后面的一个元素(这里是关键)!

有了上面的知识后,我编写了下面的代码(头文件略去),删去矢量vals中的1:

 int main()
{
vector<int> vals;
vals.push_back();
vals.push_back();
vals.push_back();
vals.push_back();
vals.push_back();
vals.push_back();
vals.push_back();
vals.push_back(); vector<int>::iterator itr = vals.begin(); while ( itr != vals.end())
{
if ( == *itr)
{
vals.erase(itr);
}
else
++itr;
}
itr = vals.begin(); while(itr != vals.end())
{
cout << *itr << endl;
itr++;
}
return ;
}

编译通过,但是调试就报错:

所以我进行了断点调试,发现第一个1可以成功删除,但是第二次试图遍历vals的时候,就会报错,看半天代码,无果,在网上搜了一些帖子,终于知道,原来,容器在删除或者插入一个元素之后,原来的迭代器会失效,于是第二次遍历时的判断条件还继续用原来的迭代器,系统无法判断是什么东西,于是报错,怎么解决呢?但是C++设计者早就为我们铺好了路,虽然erase()使得原来的迭代器失效了,但是上面说过,erase()会返回一个迭代器,返回的迭代器指向刚才所删除元素后面的一个元素,于是我们就要利用好这个返回的迭代器,更改代码如下:

就是把上面代码中的第19行改为:

itr = vals.erase(itr);

这样,原来的迭代器失效了,但是返回的迭代器又重新赋给了itr,于是工作可以继续了,运行结果如下:

所以说看一百遍不如自己亲自实践一遍,看似简单的问题,没想到花了如此长的时间,事无巨细,实践为真!

最新文章

  1. [ZigBee] 7、ZigBee之UART剖析(ONLY串口发送)
  2. 【转】Python中string的strip,lstrip,rstrip用法
  3. Laravel教程 二:路由,视图,控制器工作流程
  4. eclipse内存设置,tomcat内存设置,查看内存大小
  5. http是什么?
  6. ajax请求简写
  7. Bluetooth
  8. 关于this的指向问题
  9. redis 基础学习总结
  10. Struts2-整理笔记(二)常量配置、动态方法调用、Action类详解
  11. 用css3实现社交分享按钮
  12. vue数据双向绑定原理
  13. xe Style
  14. linux文件格式转换:&lt;U+FEFF&gt; character showing up in files. How to remove them?
  15. js中获取css样式的两种方式
  16. 词嵌入向量WordEmbedding
  17. ufw坑
  18. XSD-学习总结
  19. HDU - 6103 :Kirinriki(不错的尺取法)
  20. 如何在html文件中导入header、footer等

热门文章

  1. POI取消科学计数法
  2. ASP.NET Cookie对象到底是毛啊?(简单小例子)
  3. js正则表达式中=s.g表示什么意思
  4. C# 实现无焦点窗体(转载)
  5. 事务处理: databse jdbc mybatis spring
  6. c#中@符号作用
  7. 在linnux下,配置自动备份oacle
  8. WebBrowser的各种使用方法(未完待续)(XE8+WIN7)
  9. 支付结果回调v7核心,投保确认接口..
  10. Oracle 10进制转36进制