C++标准库学习之 STL Removing 操作

在研究 STL 的remove 操作时,有很多让我非常意外的问题,使用下面例子来说一下

c 复制代码
#include <iostream>
#include <list>
#include <algorithm>

int main(){


    // 创建一个向量,带有初始内容
    std::list<int> tsm_vector ={1,2,3,4,5,6,7,8,9};

    // 先删除  5 这个节点,删除成功后,尾结点会向前移动
    auto remove=    std::remove(tsm_vector.begin(),tsm_vector.end(),5);

    for (auto item:tsm_vector){
        std::cout<< item<<std::endl;
    }

    return 0;
}

结果:

vbnet 复制代码
D:\CWorkSpace\tsmTest\cmake-build-debug\tsmTest.exe
1
2
3
4
6
7
8
9
9

Process finished with exit code 0

在删除后发现所有节点都向前移动了,但是最后一个节点他没管,看了一下他的源码,发现他的源码就是不停的向后遍历,

那么该如何删除掉最后这个无用的9呢,

c 复制代码
#include <iostream>
#include <list>
#include <algorithm>

int main(){

    // 创建一个向量,带有初始内容
    std::list<int> tsm_vector ={1,2,3,4,5,6,7,8,9};

    // 先删除  5 这个节点,删除成功后,尾结点会向前移动
    auto remove=    std::remove(tsm_vector.begin(),tsm_vector.end(),5);

    // 在使用 erase 方法擦除无用节点
    tsm_vector.erase(remove,tsm_vector.end());
    
    for (auto item:tsm_vector){
        std::cout<< item<<std::endl;
    }

    return 0;
}

在使用完 remove 后,这个方法会返回他删除后最新的最后一个节点,也就是新的 end ,我们只需要使用 erase[remove,eng) 这个区间就可以了

那我们能直接使用 erase 直接参数吗, 答案肯定是可以的,

c 复制代码
#include <iostream>
#include <list>
#include <algorithm>

int main() {


    // 创建一个向量,带有初始内容
    std::list<int> tsm_vector = {1, 2, 3, 4, 5, 6, 7, 8, 9};

    // 先删除  5 这个节点,删除成功后,尾结点会向前移动
    auto remove = std::remove(tsm_vector.begin(), tsm_vector.end(), 5);

    // 在使用 erase 方法擦除无用节点
    tsm_vector.erase(remove, tsm_vector.end());

    for (auto item:tsm_vector) {
        std::cout << item << std::endl;
    }


    std::cout << "----------------使用 remove 后,在使用 erase-------------------" << std::endl;

    std::cout << "----------------直接使用 erase-------------------" << std::endl;

    std::list<int>::iterator start = tsm_vector.begin();
    
    while (start!=tsm_vector.end()){
        if (*start % 2 == 0) {
            // 使用擦出后的地址继续遍历,否则原来的start 会指向野指针,导致while 循环出错,
            start=tsm_vector.erase(start);
        } else {
            start++;
        }
    }

    for (auto item:tsm_vector) {
        std::cout << item << std::endl;
    }

    return 0;
}

为什么remove 无法删除数据而 erase 可以呢,在 STL 算法的设计初衷就是为了程序的扩展性等等情况考虑的, remove 等方法是与 容器脱离的,而erase 是容器自身的方法,容器自身肯定是知道容器内部的情况的,所以就形成了现在的情况

上面的例子我们使用的是 std::remove 方法,这个是 algorithm 算法库为我们提供的一个方法,想要更方便的移除该如何操作呢,

那就是调用容器的remove 方法

arduino 复制代码
std::list<int> tsm_vector = {1, 2, 3, 4, 5, 6, 7, 8, 9};

// 调用 tsm_vector 这个容器的 remove 方法即可快速的移除数据
tsm_vector.remove(5);
相关推荐
神仙别闹1 小时前
基于 C++ 实现(控制台)学生成绩管理系统
开发语言·c++
会周易的程序员1 小时前
5 节点边缘冗余方案(上):基于 aiRaft 的物联网高可用控制面设计
c++·分布式·物联网·raft·iot·共识
qq_199886875 小时前
第6板块·第4节:构建系统与多文件项目
c++·人工智能·gpu算力
汉克老师6 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者6 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
天若有情6736 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_199886877 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao17338377 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
shada8 小时前
Boost.Process v2 在旧内核上报 `assign: Bad file descriptor`
c++
别动我齐刘海8 小时前
ROS2 Jazzy + C++ 实战路线——基础学习2
c++·人工智能·vscode·python·学习·机器学习·机器人