C++ 中 remove 与 erase 的理解
参考链接
- vector的remove和erase函数的区别
- remove() 和 erase()的配合使用和remove()的作用
- stl中的remove返回的是什么
erase 简介
vector
中 erase
函数原型如下:
iterator erase(const_iterator position);iterator erase(const_iterator first,const_iterator last);
用于删除 vector 容器中的一个或者一段元素。
在删除一个元素的时候,其参数为指向相应元素的迭代器;而在删除一段元素的时候,参数为指向一段元素的开头的迭代器以及指向结尾元素的下一个元素的迭代器。
调用 erase
后,vector
元素会向前移,因此需要格外注意这个特征,避免越界访问以及漏处理。
示例代码:
int main(int argc, char *argv[])
{vector<int> myVector;myVector.push_back(1);myVector.push_back(2);myVector.push_back(3);myVector.push_back(3);myVector.push_back(3);myVector.push_back(4);myVector.push_back(3);myVector.push_back(3);myVector.push_back(3);for (vector<int>::iterator itr = myVector.begin(); itr != myVector.end(); itr++) {if (*itr == 3) {//此时itr已经指向了新的下一个元素;如果不执行itr--与itr++做抵消,则会超出end导致崩溃。itr = myVector.erase(itr);itr--;}}cout << "[After erase] myVector: ";for (int temp : myVector)cout << temp << " ";cout << endl;return 0;
}
remove 简介
algorithm
中 remove
原型如下:
template<class ForwardIterator, class Type>
ForwardIterator remove(ForwardIterator first,ForwardIterator last,const Type& value);template<class ExecutionPolicy, class ForwardIterator, class Type>
ForwardIterator remove(ExecutionPolicy&& exec,ForwardIterator first,ForwardIterator last,const Type& value);
remove
函数是由 STL
库中 algorithm
提供的一个函数,这里的 remove
字面意思很容易引起初学者误解。因为调用以后并非真实的 remove
。
代码示例
#include <vector>
#include <iostream>
#include <algorithm>using namespace std;int main(int argc, char *argv[])
{vector<int> array;array.push_back(1);array.push_back(2);array.push_back(3);array.push_back(3);array.push_back(4);array.push_back(5);cout << "init : ";print(array);array.erase(array.begin());cout << "erase array.begin() :";print(array);vector<int>::iterator remove2It = remove(array.begin(), array.end(), 2);cout << "remove 2 : ";print(array);cout << "remove2It traverse : ";for (; remove2It != array.end(); remove2It++)cout << *remove2It << " ";cout << endl;vector<int>::iterator remove3It = remove(array.begin(), array.end(), 3);cout << "remove 3 : ";print(array);cout << "remove3It traverse : ";for (; remove3It != array.end(); remove3It++)cout << *remove3It << " ";cout << endl;return 0;
}
运行后打印如下:
init : 1 2 3 3 4 5
erase array.begin() :2 3 3 4 5
remove 2 : 3 3 4 5 5
remove2It traverse : 5
remove 3 : 4 5 5 5 5
remove3It traverse : 5 5
代码分析
如上所示,执行 array.erase(array.begin());
后,符合预期地将第一个元素删除了,打印结果为:erase array.begin() : 2 3 3 4 5
。
在此基础(2 3 3 4 5
)上执行 remove(array.begin(), array.end(), 2);
,可能惯性思维会觉得得到的结果(这个是错误的结果,效果就像调用了 erase 一样)应该是 3 3 4 5
,4 个元素。而实际打印结果为:3 3 4 5 5
,5 个元素。这里完全“颠覆”了对 remove 这一字义的认识。
remove 是如何工作的?
查找资料后发现,remove
和 erase
存在很大的区别。
remove
是 algorithm
的模板函数,它接收的都是迭代器参数,并不接收某个容器。remove
并不知道它作用于哪个容器,也不可能发现容器,因为没有办法从一个迭代器获得对应于它的容器。
想要从容器中删除一个元素,唯一的方法就是调用容器的一个成员函数,比如 erase
函数。而 remove
无法知晓,故不可能根据一个传进来的迭代器进而在该容器中除去元素。因此,调用 remove
后并不会改变该容器的元素个数。
得出的结论是:remove
并不是真的在删除元素,因为它根本做不到。
remove 的工作流程
(注意:begin
与 end
是左闭右开区间,即 end
是 vector
之外了,即 vector
最后一个元素的下一个。)
这里需要明确一点是,remove()
的返回值是一个 iterator
。
再来看 remove(3) 的过程:
至此,大概可以弄清楚 remove
这个函数对一个 vector
做了哪些操作,改变了哪些元素的顺序,以及返回值是指向何处。
综上,以上是个人结合其他大神资料的理解,如有错误欢迎指出交流。
C++ 中 remove 与 erase 的理解相关推荐
- 奥莉嘎!!!ArrayList源码中remove、removeAll、clear方法我又肝了一遍,收获良多
前言 点赞在看,养成习惯. 点赞收藏,人生辉煌. 点击关注[微信搜索公众号:编程背锅侠],第一时间获得最新文章. 看源码血泪史 刚开始工作面试的时候,面试官经常问ArrayList源码相关的问题,基本 ...
- React router 的 Route 中 component 和 render 属性理解
React router 的 Route 中 component 和 render 属性理解 Route 标签的三个互斥属性 render.component.children Route 就是用来匹 ...
- python函数def里面嵌套def,python菜鸟求问关于嵌套函数中作用域范围应该怎么理解?,python嵌套,直接上代码def l(l...
python菜鸟求问关于嵌套函数中作用域范围应该怎么理解?,python嵌套,直接上代码def l(l 直接上代码def l(list): def d(): return list return d ...
- 7.STM32中对DMA_Config()函数的理解(自定义)测试DMA传输数据时CPU还可继续工作其他的事
STM32中对DMA_Config()函数的理解(自定义):
- 4.STM32中对USART1_Config()函数的理解(自定义)
STM32中对USART1_Config()函数的理解
- 3.STM32中对EXTI_PE5_Config()函数的理解(自定义)之中断控制按键LED
STM32中对EXTI_PE5_Config()函数的理解(自定义)
- 2.STM32中对Key_GPIO_Config()函数的理解(自定义)之轮询控制按键LED
STM32中对Key_GPIO_Config()函数的理解(自定义)
- 1.STM32中对LED_GPIO_Config()函数的理解(自定义)之流水灯
STM32中对LED_GPIO_Config()函数的理解(自定义)
- python threading模块的方法_Python THREADING模块中的JOIN()方法深入理解
看了oschina上的两个代码,受益匪浅.其中对join()方法不理解,看python官网文档的介绍: join([timeout]):等待直到进程结束.这将阻塞正在调用的线程,直到被调用join() ...
最新文章
- Verilog代码规范I
- 中国交通标志识别,德国交通标志识别
- 一年半跻身网约车业务前二,现发起首个自动驾驶联盟,T3出行是一家怎样的公司?...
- Redis概述与Redis集群(一)
- oracle中asm磁盘不足,Oracle用户无法访问ASM磁盘组问题
- DCMTK:DcmFloatingPointDouble类的测试程序
- irobot擦地机器人故障_irobot擦地机器人有必要入手吗?
- c++怎么保存汉字_“的汉字 ”写作练习
- 【codevs1174】 靶形数独,暴力解决问题
- 【Java】Java趣味分享:try finally
- httpget请求设置长度_Citrix ADCHTTP请求Smuggling详解
- 关于PhpDE zend ide破解方式
- 深度学习笔记:随机种子的作用
- 极客日报:华为拿百亿资金给员工分红,每股1.58元;苹果将推出M2芯片入门级MacBook Pro;Flutter 2.10发布
- HashMap源码阅读启读
- 关于ffmpeg如何下载、安装和使用
- J9数字论:如何去在Web2和Web3的融合中获得自己的优势呢?
- 成都java培训班要多少钱
- 无线串口模块通信技术参数快速选型指南
- SAP FICO 如何看一个总账科目的修改记录?