目录1. 有序集合如 C 的 std::set2. 无序集合如 C 的 std::unordered_set 或 Python 的 set正确的“修改”方式extract 的核心原理代码演示1. 修改 std::set 中的元素2. 修改 std::map 中的键Keyextract 的三大核心优势在 C 以及绝大多数编程语言中set集合中的元素不允许被直接修改其根本原因在于直接修改元素会破坏底层数据结构的规则和约束从而导致数据结构失效。我们可以从底层数据结构的角度来剖析这个问题1. 有序集合如 C 的std::setstd::set的底层通常是由红黑树一种自平衡二叉查找树实现的。排序规则约束红黑树在插入元素时会根据元素的值自动进行排序默认从小到大。树中的每一个节点的位置都是由它的值决定的左子树的值 根节点的值 右子树的值。修改带来的灾难如果允许直接修改树中某个节点的值比如把一个原本很小的值改成了很大的值这个节点所在的位置就不再符合二叉查找树的性质了。这会直接导致整棵红黑树“坍塌”后续的查找、插入和删除操作都会失效比如二分查找时会走错分支永远找不到目标元素。2. 无序集合如 C 的std::unordered_set或 Python 的set无序集合的底层通常是由哈希表Hash Table实现的。哈希映射约束当一个元素被放入哈希表时系统会计算它的哈希值Hash Code并根据这个哈希值将它放到特定的“桶”Bucket里。修改带来的灾难如果你直接修改了元素的值它的哈希值通常也会随之改变。但是这个元素目前仍然待在旧哈希值对应的“桶”里。当你要查找或删除修改后的新值时系统会去新哈希值对应的桶里找自然一无所获而旧的桶里则留下了一个“幽灵”数据导致内存泄漏或逻辑错误。正确的“修改”方式因为不能原地修改如果确实需要更新set中的某个元素必须遵循“先破后立”的原则分为两步删除旧元素erase插入新元素insert#includeiostream#includesetintmain(){std::setintmySet{10,20,30};// 假设我们要把 20 修改为 25autoitmySet.find(20);if(it!mySet.end()){// *it 25; // 编译报错表达式必须是可修改的左值 (因为迭代器返回的是 const 引用)mySet.erase(it);// 1. 删除旧值mySet.insert(25);// 2. 插入新值}return0;}在 C 中set的迭代器被设计为返回const引用正是为了从编译器层面强制阻止你直接修改它的值。在 C17 中确实引入了一种极其优雅且高效的机制来解决这个问题extract方法与节点句柄Node Handle。传统的eraseinsert做法最大的性能瓶颈在于内存分配与释放。erase会销毁树节点并释放内存而insert又会重新申请内存并拷贝/移动数据。在对常数级时间开销敏感的算法场景下这种反复的堆内存Heap操作代价高昂。C17 的extract完美绕过了这个瓶颈。extract的核心原理extract方法可以将一个节点直接从set或map的底层红黑树中“摘除”解除指针链接但不释放该节点占用的内存也不调用元素的析构函数。它会返回一个节点句柄node_type这个句柄拥有该节点的所有权。通过这个句柄你可以直接修改元素的键值然后再用insert把这个节点“挂”回到树中。整个过程仅仅是修改了几次树节点的指针零内存分配Zero Allocation也没有任何元素的拷贝或移动操作。代码演示1. 修改std::set中的元素在set的节点句柄中可以通过.value()直接修改被摘除元素的值。#includeiostream#includesetintmain(){std::setintmySet{10,20,30};// 1. 提取值为 20 的节点autonodemySet.extract(20);// 检查是否成功提取如果元素不存在node 会为空if(!node.empty()){// 2. 直接在内存中修改它的值node.value()25;// 3. 将修改后的节点重新插入回树中// 注意必须使用 std::move 转移所有权mySet.insert(std::move(node));}for(intx:mySet){std::coutx ;// 输出: 10 25 30}return0;}2. 修改std::map中的键Key修改map的 Key 一直是个痛点C17 之前只能复制 Value 再删除旧 Key。现在可以通过节点句柄的.key()直接修改。#includeiostream#includemap#includestringintmain(){std::mapint,std::stringmyMap{{1,Apple},{2,Banana}};// 提取 Key 为 1 的节点autonodemyMap.extract(1);if(!node.empty()){// 直接修改 Key不需要拷贝 Apple 字符串node.key()3;myMap.insert(std::move(node));}// 此时 myMap 变为: {2: Banana, 3: Apple}return0;}extract的三大核心优势极致的性能规避了new和delete带来的动态内存开销也避免了复杂对象如长字符串、大结构体的拷贝/移动成本。容器间转移除了修改键值你还可以用extract将一个节点从std::set转移到另一个std::set甚至是从std::set转移到std::multiset同样不需要任何内存分配操作。异常安全性因为没有发生内存分配重新insert节点句柄的操作是不会抛出std::bad_alloc异常的这在编写高健壮性代码时非常关键。如果你的数据结构中存储的是体积较大的对象或者在进行高频的键值更新C17 的extract是目前的最佳实践。
企业数字化 ERP 产品动态
相关推荐
Sunshine游戏串流完整指南:3步搭建你的家庭游戏云 Sunshine游戏串流完整指南:3步搭建你的家庭游戏云 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine
Sunshine是一款开源自托管的游戏串流服务器,专为Moonligh… · 2026/11/2 17:17:30
《Windows 11 从入门到精通》1.4.5:新的右键菜单详解 🔥 个人主页: 杨利杰YJlio ❄️ 个人专栏: 《Windows 疑难杂症与工单复盘案例库》 《Sysinternals实战教程》 《WINDOWS教程》 《Windows PowerShell 实战》 《IOS插件分析测试》 《超简单:用Python让Excel飞起来》… · 2026/11/1 18:31:41
DM37x调试接口时序解析:ETM、SDTI与JTAG的硬件设计实战 1. 项目概述在嵌入式系统开发,尤其是基于德州仪器(TI)DM37x系列这类高性能异构SoC的项目中,调试接口的设计往往是硬件工程师最容易“踩坑”的地方。你可能遇到过这样的情况:精心设计的板子,软件工程师却抱怨… · 2026/9/29 4:48:46
常宁办理电工证多久拿证,学历不高也能考?全攻略来了 常宁办理电工证多久拿证,学历不高也能考?全攻略来了 你是不是也担心自己学历不高,根本报不了电工证?别急,常宁办理电工证其实对学历门槛并没有那么高,关键在于你是否了解流程和要求。今天我们就来聊聊, 常宁办理电工证多久拿证… · 2026/11/9 22:28:24
高要电工证多少钱官方报名入口怎么找 高要电工证多少钱官方报名入口怎么找 实操考试心里没底怕挂科,特别是第一次考电工证的新手,担心操作不熟练、动作不规范,导致考试失败。其实,只要准备充分,掌握好考试流程和标准,就能提高通过率。本文围绕【高要电工证多少钱】这一关键词,结合洛阳培训… · 2026/11/9 22:28:24
考电工证有哪些途径 电子证书怎么拿 电工证不考就失业 考电工证有哪些途径 电子证书怎么拿 电工证不考就失业 你现在缺的是电工证,缺的是电子证书,缺的是能让你上岗的资质。别等到面试时被问“你有电工证吗”才后悔,电工证是你进入电力行业、建筑行业、制造业等岗位的“入场券”,没有它,你连面试的机会都没… · 2026/11/9 22:28:24
贵阳三机能报考电工证内部消息:学历不高怕报不上名?其实你也能上岸! 贵阳三机能报考电工证内部消息:学历不高怕报不上名?其实你也能上岸! 你是不是也这样?学历不高,担心贵阳三机能报考电工证报名条件太严格,怕自己连资格都没?别慌,这里有个【内部消息】,告诉你:学历不是门槛,操作证才是你真正的通行证。今天我就来给… · 2026/11/9 22:28:24
湖北省特种工年龄限制2026河南最新政策下如何破局 湖北省特种工年龄限制2026河南最新政策下如何破局 你是不是也担心自己学历不高,报名特种作业操作证会受限制?2026河南最新政策明确, 湖北省特种工年龄限制… · 2026/11/9 22:28:24
广安电工证怎么选 上岗必备证书怎么考更划算 广安电工证怎么选 上岗必备证书怎么考更划算 之前考的证在外省能不能转过来?这个问题几乎每个想从事电工岗位的朋友都问过,特别是在广安这样的地方,很多人担心自己手里的证书不能用,或者换地方后需要重新考证。但事实上,只要你是通过… · 2026/11/9 22:27:24
电工证丢失还能补吗?千万别踩坑,丢了证等于失业 电工证丢失还能补吗?千万别踩坑,丢了证等于失业 你正在找工作,但手里的电工证突然丢了,这下怎么办?别急,先别慌, 电工证丢失还能补吗 ?答案是肯定的,但 千万别踩坑 ,补办流程如果不了解,可能会耽误你上岗、甚至影响到你的收入。… · 2026/11/9 2:05:04
电力电缆作业证直播报名入口与办理流程良心建议 电力电缆作业证直播报名入口与办理流程良心建议 你是不是也担心学历不高报不了名?别急,今天就给你讲讲 电力电缆作业证直播 的报名流程和那些你必须知道的干货, 良心建议 在这里,别错过。 电力电缆作业证直播报名需要什么条件?… · 2026/11/9 3:11:26
英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 英德电工证报考费多少钱,怕考不过白交培训费?看完这篇别再踩坑 怕考不过白交培训费?英德电工证报考费多少钱,你真的了解吗?现在市面上培训机构五花八门,价格参差不齐,很多人一不小心就花了冤枉钱,结果还考不过。别急,今天就来给你说清楚英德电工证的… · 2026/11/9 5:24:17
电工证不需要考复审延期怎么办理 通过率揭秘 电工证不需要考复审延期怎么办理 通过率揭秘 不知道去哪报名怕被中介坑?电工证不需要考复审延期怎么办理?最近不少学员都在问这个问题,尤其是刚拿到证的新手,对复审流程一知半解,生怕被培训机构套路。别担心,今天咱们就来聊聊电工证复审的真相,尤其是… · 2026/11/9 0:00:54
砀山哪里考电工证的多 电工证报考别踩坑 郑州报考避坑指南 砀山哪里考电工证的多 电工证报考别踩坑 郑州报考避坑指南 工地太忙根本没时间复习考试,这几乎是所有一线施工人员的共同心声。尤其是像电工这样的特种作业,操作证不仅关系到能不能上工,还直接关系到工资高低和职业发展。可偏偏,很多人连怎么报名、去哪… · 2026/11/9 0:00:54
南方电网电工作业含金量高吗?应届生怎么考怎么干? 南方电网电工作业含金量高吗?应届生怎么考怎么干? 工地太忙根本没时间复习考试,这不是个别现象,而是很多刚毕业的工程类学生面临的现实。南方电网电工作业的证书,听起来门槛不低,但 含金量… · 2026/11/9 0:00:54
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/9 11:23:35
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/9 11:23:58
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/9 11:25:08