• 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()位置。我们可以按照下面这样来写:

    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将数据结构和算法分离开来。然而,迭代器只不过是“容器中某一位置”的抽象概念而已。一般来说,迭代器对自己所属的容器一无所知任何“以迭代器访问容器元素”的算法,都不得(无法)透过迭代器调用容器类别所提供的任何成员函数

  • 相关阅读:
    第二周作业
    第一次作业
    第0次作业
    第一次的作业
    第0次作业
    第三次作业
    %f使用时的注意事项
    关于c++停止工作
    第二次作业
    第一次作业
  • 原文地址:https://www.cnblogs.com/ziyoudefeng/p/2421909.html
Copyright © 2020-2023  润新知