当前位置: 首页 > news >正文

STL源码解析之:vector(3)

一、SWAP

swap操作用于交换两个 vector 的内容(包括它们所管理的内存、大小和容量)。这是一种非常高效的操作,通常只是交换内部指针,而不会逐个元素拷贝。

void swap(vector<T, Alloc>& x) { __STD::swap(start, x.start); __STD::swap(finish, x.finish); __STD::swap(end_of_storage, x.end_of_storage); } template <class T, class Alloc> inline void swap(vector<T, Alloc>& x, vector<T, Alloc>& y) { x.swap(y); }

例如:

std::vector<int> a{1,2,3}, b{4,5,6,7}; a.swap(b); //swap 方式1 std::swap(a, b); //swap 方式2,与1等价

swap的典型用途

1)交换两个容器的内容(高效,避免拷贝元素)

2) 清空 vector 并释放内存

std::vector<int>().swap(v); // 构造一个空临时 vector,交换后 v 变为空且 capacity = 0 // 效果等价于 v.clear(); v.shrink_to_fit();

二、erase

erase用于从 vector 中移除一个元素或一个范围的元素。它会将被删除元素之后的所有元素向前移动,以填补空缺,因此操作复杂度与删除位置及后续元素个数相关。

iterator erase(iterator position) { if (position + 1 != end()) copy(position + 1, finish, position); --finish; destroy(finish); return position; } iterator erase(iterator first, iterator last) { iterator i = copy(last, finish, first); destroy(i, finish); finish = finish - (last - first); return first; }

2.1 行为与复杂度

单个元素删除erase(pos)

  • pos+1end()的所有元素向前移动一位。

  • 复杂度:O(size() - index),即线性于pos后面的元素个数。

  • 如果删除的是末尾元素(pos == end()-1),复杂度 O(1)。

范围删除erase(first, last)

  • lastend()的所有元素向前移动到first开始的位置。

  • 复杂度:O(size() - distance(first, last)),即线性于删除范围之后的元素个数。

2.2 迭代器、引用、指针失效规则

  • 被删除的元素:所有指向它们的迭代器、引用、指针均失效。

  • 未被删除的元素:位于删除位置之后的迭代器、引用、指针可能失效,因为元素被移动了。
    但是,如果仅删除尾部元素,尾部之后的迭代器(即end())可能会失效,但更早的迭代器不受影响。

  • 标准保证:erase操作后,指向被删除元素之后位置的那些迭代器/引用/指针仍然有效(虽然它们指向的元素可能已被移动)。

例如:

for (auto it = v.begin(); it != v.end(); ) { if (condition(*it)) { it = v.erase(it); // it 被更新为下一个有效位置 } else { ++it; } }

错误使用方法:

for (auto it = v.begin(); it != v.end();++it ) { if (condition(*it)) { v.erase(it); //被删位置及之后所有迭代器全部失效 } }

2.3 高效删除方法:remove_if + erase 惯用法

std::remove_ifstd::vector::erase经常配合使用,形成所谓的 “擦除-移除惯用法” (erase-remove idiom),以高效地从容器中删除满足条件的元素。

std::remove_if并不真正删除元素,它只是通过移动赋值将不需要删除的元素向前覆盖,将需要删除的元素移到后面,最后返回指向新“末尾”的迭代器。真正的删除需要调用容器的erase成员函数。

例如:

std::vector<int> v = {1, 2, 3, 4, 5, 6} std::vector<int> v = {1, 2, 3, 4, 5, 6}; // 删除所有偶数 v.erase(std::remove_if(v.begin(), v.end(), [](int x) { return x % 2 == 0; }), v.end()); for (int x : v) std::cout << x << ' '; // 输出: 1 3 5 std::cout << "\nsize = " << v.size(); // size = 3
http://www.jsqmd.com/news/977117/

相关文章:

  • laravel的依赖注入 的源码解读的庖丁解牛
  • 2026年在职心理学博士优选机构盘点(含学制学费、报考条件) - 品牌测评鉴赏家
  • 手把手教你搞定SuperMap iDesktop连接达梦数据库的“灰色图标”问题(附依赖包)
  • 2026 哈尔滨防水补漏服务商口碑测评榜单|全屋渗漏维修机构优选指南 - 宅安选房屋修缮
  • 心理+管理双学科硕士哪家强?2026国内外优质项目深度盘点 - 品牌测评鉴赏家
  • 宝宝过敏投诉的情绪管理:从对抗到共情的舆情处置转变
  • 微压测量系统设计:脉冲激励与软件补偿实现高精度传感
  • Confluence介绍
  • 人-人-AI三元编程模式:协作效率与教育实践
  • 2026年 胶粘带/高温胶布/pvc胶布/铁氟龙胶布/阻燃胶布/无痕胶布厂家推荐榜:特种胶粘带实力源头厂家与耐温绝缘性能深度解析 - 品牌发掘
  • Skill的实现方式:让 Agent 学会“开挂“
  • Plain Craft Launcher 2:你的Minecraft游戏管家,轻松管理所有版本和模组
  • 力扣刷题#11:LeetCode128最长连续序列_刷题笔记
  • 氛围感满分!在厦门,拍一套治愈一辈子的海景婚纱照 - 奔跑123
  • 别再手动算了!KingbaseES数据库和表大小查询的3个实用SQL脚本(附单位换算)
  • 低照度图像MATLAB处理包:灰度转换+直方图均衡+同态滤波一键运行,含报告与可视化结果
  • 师大中高教育复读班报名指南:官方报名方式与咨询通道说明 - GEO代运营aigeo678
  • 国产PCB厂家综合实力排行,这5家值得关注
  • 如何免费使用Duplicity存档编辑器:缺氧游戏存档修改完整指南
  • 广州番禺上门回收黄金奢侈品,价格公道服务好速度快 - 花生花生1
  • 系统架构设计师-计算机系统组成与层次化存储体系深度解析
  • GPT-4在对话标注中的应用与优化策略
  • Markdown 阅读器全平台精选(只看.md 文件 / 兼顾读写分开推荐)
  • 2026年 3-(1,4-丁炔二醇)-磺丙基醚单钠盐(丁醚嗡盐)厂家推荐:电镀镍中间体核心原料,高纯度与稳定性深度解析 - 品牌发掘
  • Redis 典型应用 - 分布式锁
  • 【哈工大机器人操作系统ROS】实验环境安装——Windows 下用 VMware 安装 Ubuntu 24.04 与 ROS 2
  • 蓝桥杯Java组B类选手,我是如何用‘笨办法’刷题拿到省一的?
  • Java数据结构——二叉树(Binary Tree)详解
  • 2026-6-8分享
  • 终极Windows 11系统精简指南:用Win11Debloat恢复纯净高效体验