STL标准库algorithm中remove()函数的一个小注意事项

先给一个小程序,大家猜一下结果是什么:

 1 // StandLibP112.cpp : 定义控制台应用程序的入口点。
2 //
3
4 #include "stdafx.h"
5 #include <vector>
6 #include <algorithm>
7 #include <iostream>
8
9 using namespace std;
10
11 int _tmain(int argc, _TCHAR* argv[])
12 {
13
14 vector<int> vec;
15
16 for ( int i = 0; i < 10; ++i )
17 {
18 vec.push_back(i);
19 }
20
21 copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
22 cout << endl;
23
24 remove(vec.begin(), vec.end(), 3);
25 copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
26 cout << endl;
27
28 return 0;
29 }

结果:

0 1 2 3 4 5 6 7 8 9
0 1 2 4 5 6 7 8 9 9
请按任意键继续. . .

为什么会是这样呢?

原因是remove()并没有改变vec的元素数量,他只是找到这个3之后,把3改变为它后续的元素,即3->4, 4->5, 5->6,...,8->9。然后9这个位置依然是9。

其实remove()的返回值是删除了vec中的3之后实际的.end()位置。我们可以按照下面这样来写:

STL标准库algorithm中remove()函数的一个小注意事项View Code

vector<int>::iterator end = remove(vec.begin(), vec.end(), 3);
copy(vec.begin(), end, ostream_iterator<int>(cout, " "));

这样写的输出就是:

0 1 2 4 5 6 7 8 9
请按任意键继续. . .

其实,如果我们真的需要删除该元素的话,可以这样写:

vec.erase( remove(vec.begin(), vec.end(), 3), vec.end() );

 

remove()的注意事项讨论结束,但有一个问题缠绕着我们,为什么标准库algorithm里面的remove()不自己调用erase()呢?

  下面摘抄《C++ 标准程序库》一书P114上一段话:

  这个问题正好点出STL为了获取灵活性而付出的代价。透过“以迭代器为接口”,STL将数据结构和算法分离开来。然而,迭代器只不过是“容器中某一位置”的抽象概念而已。一般来说,迭代器对自己所属的容器一无所知任何“以迭代器访问容器元素”的算法,都不得(无法)透过迭代器调用容器类别所提供的任何成员函数

原文链接: https://www.cnblogs.com/ziyoudefeng/archive/2012/03/28/2421909.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    STL标准库algorithm中remove()函数的一个小注意事项

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/45510

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 下午10:01
下一篇 2023年2月8日 下午10:02

相关推荐