Effective STL 第9条:C++容器元素删除技巧详解

Effective STL 第9条:C++容器元素删除技巧详解

  • 删除特定值的所有对象
    • [1. 连续内存容器(vector, string, deque)](#1. 连续内存容器(vector, string, deque))
    • [2. 链表容器(list)](#2. 链表容器(list))
    • [3. 标准关联容器(set, multiset, map, multimap)](#3. 标准关联容器(set, multiset, map, multimap))
  • 删除满足特定条件的对象
    • [1. 序列容器(vector, string, deque, list)](#1. 序列容器(vector, string, deque, list))
    • [2. 标准关联容器](#2. 标准关联容器)
  • 循环内执行额外操作时的删除
    • [1. 序列容器](#1. 序列容器)
    • [2. 关联容器](#2. 关联容器)
  • 总结

在C++编程中,高效地从容器中删除元素是一项基本但至关重要的技能。本文将详细介绍针对不同类型容器的元素删除方法,帮助开发者编写更高效、更安全的代码。

删除特定值的所有对象

1. 连续内存容器(vector, string, deque)

对于连续内存容器,推荐使用erase-remove习惯用法【1†source】【5†source】:

cpp 复制代码
c.erase(remove(c.begin(), c.end(), 1963), c.end());

这里remove操作并不会真正移除元素,而是将后面的元素覆盖要删除的元素,并返回新区间的逻辑终点。随后erase负责删除两个迭代器之间的元素。

2. 链表容器(list)

对于list容器,直接使用成员函数remove更为高效【1†source】:

cpp 复制代码
c.remove(1963);

3. 标准关联容器(set, multiset, map, multimap)

关联容器应使用其erase成员函数【5†source】:

cpp 复制代码
c.erase(1963);  // 对数时间复杂度,比序列容器更高效

删除满足特定条件的对象

1. 序列容器(vector, string, deque, list)

使用erase-remove_if习惯用法【1†source】:

cpp 复制代码
c.erase(remove_if(c.begin(), c.end(), badValue), c.end());

对于list,直接使用成员函数:

cpp 复制代码
c.remove_if(badValue);

2. 标准关联容器

有两种解决方案【5†source】:

方案一 :使用remove_copy_ifswap

cpp 复制代码
AssocContainer<int> goodValues;
remove_copy_if(c.begin(), c.end(), 
               inserter(goodValues, goodValues.end()), 
               badValue);
c.swap(goodValues);

方案二:使用迭代器循环删除

cpp 复制代码
for(auto i = c.begin(); i != c.end(); /* 无操作 */)
    if(badValue(*i))
        c.erase(i++);  // 后缀递增确保安全
    else
        ++i;

循环内执行额外操作时的删除

1. 序列容器

利用erase的返回值更新迭代器【1†source】:

cpp 复制代码
for(auto i = c.begin(); i != c.end(); )
    if(badValue(*i)) {
        logFile << "Erasing " << *i << '\n';
        i = c.erase(i);  // erase返回下一个有效迭代器
    } else {
        ++i;
    }

2. 关联容器

使用后缀递增确保迭代器有效性【5†source】:

cpp 复制代码
for(auto i = c.begin(); i != c.end(); /* 无操作 */)
    if(badValue(*i)) {
        logFile << "Erasing " << *i << '\n';
        c.erase(i++);  // 先递增再删除
    } else {
        ++i;
    }

总结

选择正确的删除方法需要考虑容器类型和删除条件【1†source】【5†source】:

  1. 特定值删除

    • 序列容器:erase-remove
    • list:remove
    • 关联容器:erase
  2. 条件删除

    • 序列容器:erase-remove_if
    • list:remove_if
    • 关联容器:循环删除或remove_copy_if+swap
  3. 循环内额外操作

    • 序列容器:利用erase返回值
    • 关联容器:后缀递增迭代器

掌握这些技巧可以显著提高C++程序的效率和安全性,是每个C++开发者必备的技能【1†source】【5†source】。

相关推荐
quantdash_cc1 分钟前
如何设计高效率的批量股票数据获取程序?QuantDash Python SDK 全市场行情拉取实战指南
开发语言·python·数据分析·量化交易·股票数据·quantdash
这个DBA有点耶4 分钟前
时间序列数据库选型2026:5款主流产品深度对比与场景适配
大数据·数据库·程序人生·架构·时序数据库·dba·数据库管理员
Jul1en_6 分钟前
Matt 与 Uncle Bob 的播客访谈有感
开发语言·经验分享·笔记·ai·开源·github·ai编程
玖玥拾11 分钟前
Lua 基础语法(五)Unity xLua基础配置与 C# 访问 Lua
开发语言·unity·c#·lua
淼澄研学15 分钟前
Sonos空间音频技术解析与Python本地API控制实操
开发语言·python·音视频
研☆香21 分钟前
js中使用的正则表达式
开发语言·javascript·正则表达式
szarron22 分钟前
国产手持式频谱分析仪选型攻略:TFN RC系列 vs HTOOL SA8T频谱分析仪 专业参数对比(军工/路测/调试全覆盖)
开发语言·前端·状态模式
我是唐青枫23 分钟前
C#.NET StructureMap 从依赖注入到项目实战
开发语言·c#·.net
Beyond_System|系统之外26 分钟前
一个网页如何同时适配投影仪、1366×768 和 1920×1080?我重新理解了“自适应布局”
开发语言·css·html
蛋先生DX26 分钟前
内存安全翻车现场的罪魁祸首,根源就在这三步里?
c++·后端·编程语言