首页 > 未分类 > STL笔记(4)关于erase,remove
2019
11-29

STL笔记(4)关于erase,remove

你要erase的元素很容易识别。它们是从区间的“新逻辑终点”开始持续到区间真的终点的原来区间的元素。要除去那些元素,你要做的所有事情就是用那两个迭代器调用erase的区间形式(参见条款5)。因为remove本身很方便地返回了区间新逻辑终点的迭代器,这个调用很直截了当:

STL笔记(4)关于erase,remove - 第1张  | 逗分享开发经验vector<int> v;                        // 正如从前
STL笔记(4)关于erase,remove - 第2张  | 逗分享开发经验
v.erase(remove(v.begin(), v.end(), 99), v.end());        // 真的删除所有
STL笔记(4)关于erase,remove - 第3张  | 逗分享开发经验                            
// 等于99的元素
STL笔记(4)关于erase,remove - 第4张  | 逗分享开发经验
cout << v.size();                        // 现在返回7
STL笔记(4)关于erase,remove - 第5张  | 逗分享开发经验

把remove的返回值作为erase区间形式第一个实参传递很常见,这是个惯用法。事实上,remove和erase是亲密联盟,这两个整合到list成员函数remove中。这是STL中唯一名叫remove又能从容器中除去元素的函数:

STL笔记(4)关于erase,remove - 第6张  | 逗分享开发经验list<int> li;            // 建立一个list
STL笔记(4)关于erase,remove - 第7张  | 逗分享开发经验                
// 放一些值进去
STL笔记(4)关于erase,remove - 第8张  | 逗分享开发经验
li.remove(99);            // 除去所有等于99的元素:
STL笔记(4)关于erase,remove - 第9张  | 逗分享开发经验                
// 真的删除元素,
STL笔记(4)关于erase,remove - 第10张  | 逗分享开发经验                
// 所以它的大小可能改变了
STL笔记(4)关于erase,remove - 第11张  | 逗分享开发经验

坦白地说,调用这个remove函数是一个STL中的矛盾。在关联容器中类似的函数叫erase,list的remove也可以叫做erase。但它没有,所以我们都必须习惯它。我们所处于的世界不是所有可能中最好的世界,但却是我们所处的。(附加一点,条款44指出,对于list,调用remove成员函数比应用erase-remove惯用法更高效。)

一旦你知道了remove不能“真的”从一个容器中删除东西,和erase联合使用就变成理所当然了。你要记住的唯一其他的东西是remove不是唯一这种情况的算法。另外有两种“类似remove”的算法:remove_if和unique。

remove和remove_if之间的相似性很直截了当。所以我不会细讲,但unique行为也像remove。它用来从一个区间删除东西(邻近的重复值)而不用访问持有区间元素的容器。结果,如果你真的要从容器中删除元素,你也必须成对调用unique和erase,unique在list中也类似于remove。正像list::remove真的删除东西(而且比erase-remove惯用法高效得多)。list::unique也真的删除邻近的重复值(也比erase-unique高效)。

(译注:《C++标准程序库》111页5.6节有remove的详细解释)

最后编辑:
作者:搬运工
这个作者貌似有点懒,什么都没有留下。