Effective STL 条款1:仔细选择你的容器

04-众多C++容器如何挑选? 目录前言无规律容器vectordequelist&forward_listqueue&stack有规律容器priority_queue有序关联容器无序关联容器array选择方法总结 前言 相信大家在学习C++过程中都会学习STL容器,至于容器实现的原理可以去看侯捷老师《STL源码剖析》。网上也有很多资源,为了支持正版这里就不放出来了,有需要可以评论区留言。STL容器的实现很复杂但是... 阅读详情

条款1:仔细选择你的容器

你知道C++中有很多你可以支配的容器,但是你意识到有多少吗?要确定你没有忽略你的选项,这里有一个快速回顾。

  • 标准STL序列容器:vector、string、deque和list。
  • 标准STL关联容器:set、multiset、map和multimap。
  • 非标准序列容器slist和rope。slist是一个单向链表,rope本质上是一个重型字符串。(“rope”是一个重型“string”。明白了吗?)你可以找到一个关于这些非标准(但常见的)容器的概览在条款50。
  • 非标准关联容器hash_set、hash_multiset、hash_map和hash_multimap。我在条款25检验了这些可以广泛获得的基于hash表的容器和标准关联容器的不同点。
  • vector<char>可以作为string的替代品。条款13描述了这个替代品可能会有意义的情况。
  • vector作为标准关联容器的替代品。就像条款23所说的,有时候vector可以在时间和空间上都表现得比标准关联容器好。
  • 几种标准非STL容器,包括数组、bitset、valarray、stack、queue和priority_queue。因为它们是非STL容器,所以在本书中关于它们我说得很少,虽然条款16提到了数组比STL容器更有优势的一种情况,而条款18揭示了为什么bitset可能比vector<bool>要好。值得注意的是,数组可以和STL算法配合,因为指针可以当作数组的迭代器使用。

这是所有的选项,而且可以考虑的范围和可以在它们之间的选择一样丰富。不走运的是,STL的大多数讨论只限于容器世界的一个很窄的视野,忽略了很多关于选择适当容器的问题。就连标准都介入了这个行动,提供了以下的在vector、deque和list之间作选择的指导方案:

vector、list和deque提供给程序员不同的复杂度,因此应该这么用:vector是一种可以默认使用的序列类型,当很频繁地对序列中部进行插入和删除时应该用list,当大部分插入和删除发生在序列的头或尾时可以选择deque这种数据结构。

如果你主要关心的是算法复杂度,我想这个方案是有理由的建议,但需要关心更多东西。

现在,我们要检查一些可以补充算法复杂度的重要的容器相关问题,但首先我需要介绍一种STL容器的分类方法,它被讨论的次数并不像它应该的那样多。那是连续内存容器和基于节点的容器的区别。

连续内存容器(也叫做基于数组的容器)在一个或多个(动态分配)的内存块中保存它们的元素。如果一个新元素被查入或者已存元素被删除,其他在同一个内存块的元素就必须向上或者向下移动来为新元素提供空间或者填充原来被删除的元素所占的空间。这种移动影响了效率(参见条款5和14)和异常安全(就像我们将会看到的)。标准的连续内存容器是vector、string和deque。非标准的rope也是连续内存容器。

基于节点的容器在每个内存块(动态分配)中只保存一个元素。容器元素的插入或删除只影响指向节点的指针,而不是节点自己的内容。所以当有东西插入或删除时,元素值不需要移动。表现为链表的容器——比如list和slist——是基于节点的,所有的标准关联容器也是(它们的典型实现是平衡树)。非标准的hash容器使用不同的基于节点的实现,就像我们将会在条款25中看到的。

利用这个不恰当的术语,我们已经准备好描述一些大多数关于在容器间选择的问题。在这个讨论中,我略过考虑非STL类容器(比如,数组、bitset等),因为毕竟这是本关于STL的书。

  • 你需要“可以在容器的任意位置插入一个新元素”的能力吗?如果是,你需要序列容器,关联容器做不到。
  • 你关心元素在容器中的顺序吗?如果不,hash容器就是可行的选择。否则,你要避免使用hash容器。
  • 必须使用标准C++中的容器吗?如果是,就可以除去hash容器、slist和rope。
  • 你需要哪一类迭代器?如果必须是随机访问迭代器,在技术上你就只能限于vector、deque和string,但你也可能会考虑rope(关于rope的更多信息在条款50)。如果需要双向迭代器,你就用不了slist(参见条款50)和hash容器的一般实现(参见条款25)。
  • 当插入或者删除数据时,是否非常在意容器内现有元素的移动?如果是,你就必须放弃连续内存容器(参见条款5)。
  • 容器中的数据的内存布局需要兼容C吗?如果是,你就只能用vector(参见条款16)。
  • 查找速度很重要吗?如果是,你就应该看看hash容器(参见条款25),排序的vector(参见条款23)和标准的关联容器——大概是这个顺序。
  • 你介意如果容器的底层使用了引用计数吗?如果是,你就得避开string,因为很多string的实现是用引用计数(参见条款13)。你也不能用rope,因为权威的rope实现是基于引用计数的(参见条款50)。于是你得重新审核你的string,你可以考虑使用vector<char>。
  • 你需要插入和删除的事务性(transactional)语义吗?也就是说,你需要有可靠地回退(roll back)插入和删除的能力吗?如果是,你就需要使用基于节点的容器。如果你需要多元素插入(比如,以范围的方式——参见条款5)的事务性语义,你就应该选择list,因为list是唯一提供多元素插入事务性语义的标准容器。事务性语义对于有兴趣写异常安全代码的程序员来说非常重要。(事务性语义也可以在连续内存容器上实现,但会有一个性能开销,而且代码不那么直观。要了解这方面的知识,请参考Sutter的《Exceptional C++》的条款17 [8]。)
  • 你要把迭代器、指针和引用的失效次数减到最少吗?如果是,你就应该使用基于节点的容器,因为在这些容器上进行插入和删除不会使迭代器、指针和引用失效(除非它们指向你删除的元素)。一般来说,在连续内存容器上插入和删除会使所有指向容器的迭代器、指针和引用失效。
  • 你需要具有有以下特性的序列容器吗:1)可以使用随机访问迭代器;2)只要没有删除而且插入只发生在容器结尾,指针和引用的数据就不会失效?这个一个非常特殊的情况,但如果你遇到这种情况,deque就是你梦想的容器。(有趣的是,当插入只在容器结尾时,deque的迭代器也可能会失效,deque是唯一一个“在迭代器失效时不会使它的指针和引用失效”的标准STL容器。)

这些问题几乎不是事情的完结。比如,它们没有关注不同的容器类型使用不同的内存配置策略(条款10和14讨论了这些策略的一些方面)。但是,它们已经足够是你信服了,除非你对元素顺序、标准的一致性、迭代器能力、内存布局和C的兼容性、查找速度、因为引用计数造成的行为不规则、事务性语义的轻松实现和迭代器失效的条件没兴趣,你得在容器操作的算法复杂度上花更多的考虑时间。当然这样的复杂度是重要的,但这离整个故事很远。

当面对容器时,STL给了你很多选项。如果你的视线超越了STL的范围,那就会有更多的选项。在选择一个容器前,要保证考虑了所有你的选项。一个“默认容器”?我不这么认为。

GLM-5.3-Flash生产落地实践:从API试水到多卡推理服务全记录 大模型推理服务在2024年的生产环境中已成为刚需,而如何高效部署模型、合理利用多卡异构显存、保障服务稳定性,是工程师们普遍面临的工程挑战。从概念上看,推理服务涉及模型加载、显存管理、并发调度等底层原理,不同硬件配置下的性能差异显著。技术价值体现在通过合理的架构设计,可以压榨显存利用率、降低延迟并提升吞吐。在实际应用中,无论是快速接入API验证效果,还是自建多卡集群支撑业务,都需要一套从开发到运维的完整方法论。本文基于GLM-5.3-Flash在真实生产环境的落地经验,涵盖API集成、单机异构显存适配、多卡推 阅读详情

相关推荐

【绝版C++书籍】《Effective STL》读书笔记

《Effective STL》读书笔记写在前面《Effective STL》中可能过时的内容1 容器第1条:慎重选择容器类型。第2条:不要试图编写独立于容器类型的代码。第3条:确保容器中的对象拷贝正确而高效。第4条:调用empty而不是检查size()是否为0。第5条:区间成员函数优先于与之对应的单元素成员函数。第6条:当心C++编译器最烦人的分析机制。第7条:如果入容器中包含了通过new操作创建的指针,切记在容器对象析构前将delete掉。第8条:切勿创建包含auto_ptr的容器对象。第9条:慎重选择删

Elias_Liu的博客 1757

【C++ STL】容器的选择

c++提供了各具特长的容器,那么我们该如何选择最佳的容器? 缺省状态下应该选择vector,因为vector内部结构最简单,并允许随机存取,所以数据的存取十分方便,数据的处理也快。 如果经常要在头部和尾部安插和移动元素,应该采用deque,如果希望元素被移除时,容器能够自动缩减内存,也应该使用deque。 如果经常在容器的中段执行元素的安插、移除和移动,可以使用list,lis...

240

effective stl 中文版(高清扫描版).pdf

C++的标准模板库(STL)是革命性的技术,但是要想用好STL却并不容易。在《中文版Effective STL:50条有效使用STL的经验》中,畅销书作家ScottMeyers(EffectiveC++和MoreEffectiveC++的作者)揭示了专家总结的一些关键规则,包括专家们总是采用的做法,以及专家们总是避免的做法。通过这些规则,程序员可以高效地使用STL。

如何选出最适合的C++ STL容器

如何选出最适合的C++ STL容器 总的来说,C++ STL 标准库(以 C++ 11 为准)提供了以下几种容器供我们选择: 序列式容器:array、vector、deque、list 和 forward_list; 关联式容器:map、multimap、set 和 multiset; 无序关联式容器:unordered_map、unordered_multimap、unordered_set 和 unordered_multiset; 容器适配器:stack、queue 和 priority_queue。

weixin_41167925的博客 592

家庭路由器从入门到精通:连接设置、优化排障全指南

路由器作为家庭网络的核心枢纽,其工作原理基于NAT(网络地址转换)和DHCP(动态主机配置协议)两大关键技术。NAT负责将公网IP转换为多个内网IP,实现多设备共享上网;DHCP则自动为接入设备分配IP地址,简化网络配置。这些技术共同构建了稳定、安全的局域网环境,其价值在于为智能家居、在线办公、高清影音和游戏娱乐等场景提供可靠的网络基础。理解路由器的物理连接、后台设置与故障排查逻辑,是优化Wi-Fi信号覆盖、提升网络性能、保障家庭网络安全的关键。本文以路由器配置与排障为核心,详细解析从WAN/LAN口区分、

weixin_33393017的博客 404

深度学习入门:一文详解BP神经网络

在BP神经网络中,输入层和输出层的节点个数都是确定的,而隐含层节点个数不确定,那么应该设置为多少。实际上,隐含层节点个数的多少对神经网络的性能是有影响的,有一个经验公式可以确定隐含层。上面是对隐含层和输出层之间的权值和输出层的阀值计算调整量,而针对输入层和隐含层和隐含层的阀值调。在BP神经网络中,输入层节点没有阀值。神经网络,神经网络在机器学习中应用比较广泛,比如函数逼近,模式识别,分类,数据压缩,数据。要求输入模式要有足够的随机性,对输入模式的噪声比较敏感,即对于剧烈变化的输入模式,训。

Machine Learning with Tutors 4万+

Effective STL学习

effect stl读书笔记

skyztttt的专栏 822

【OpenSearch】从零到一:手把手搭建OpenSearch与Dashboard可视化平台

本文提供了一份详细的OpenSearch与Dashboard可视化平台从零搭建指南。内容涵盖环境准备、系统调优、核心服务安装配置、Dashboard部署与汉化,以及生产环境安全加固建议,帮助用户快速构建一个功能完整的搜索与分析平台。

devops8pract的博客 617

Effective STL 50条有效使用STL的经验笔记

Scott Meyers大师Effective三部曲:Effective C++、More Effective C++、Effective STL,这三本书出版已很多年,后来又出版了Effective Modern C++。 Effective C++的笔记见:https://blog.youkuaiyun.com/fengbingchun/article/details/102761542 More E...

网络资源是无限的 1万+

一文解读DeepSeek训练数据集

本文重点以DeepSeek为例,详细介绍预训练数据集相关内容。大语言模型LLM(如DeepSeek、ChatGPT、文心一言等)的“智慧”源于它们学习的海量数据集。简单来说,数据集就是模型的“知识库”,通常由互联网公开的文本、图片、视频等。这些数据需满足两个特点:规模大和多样性。规模大是指数据量可达千亿级词汇,让模型学习复杂规律;多样性则涵盖多领域(如科技、文学)、多语言、多形式(对话、新闻),帮助模型适应不同场景。例如,训练数据中既有百科知识,也有日常对话,模型才能既解答专业问题,又能闲聊。

u013891230的博客 7080

从SolidWorks到Simulink:手把手教你用URDF文件搭建六轴机械臂仿真模型(含STL文件配置避坑)

本文详细介绍了从SolidWorks到Simulink的六轴机械臂URDF仿真全流程,包括URDF文件导出、Simscape模型生成与调试、动力学参数获取与验证等关键步骤。重点解决了STL文件配置、关节接口设置等工程化难题,帮助开发者高效构建可控制的数字孪生体。通过实战案例和优化技巧,提升机械臂仿真效率与准确性。

weixin_26812607的博客 264

Effective STL 条款1:仔细选择你的容器 (连载)

条款1:仔细选择你的容器你知道C++中有很多你可以支配的容器,但是你意识到有多少吗?要确定你没有忽略你的选项,这里有一个快速回顾。标准STL序列容器:vector、string、deque和list。 标准STL关联容器:set、multiset、map和multimap。 非标准序列容器slist和rope。slist是一个单向链表,rope本质上是一个重型字符串。(“绳子(

Wings的专栏 914

数据标注的下一代SOP,可能不是Word,而是一段Prompt

再给几个反例:“这个只是正常纹理,不算。真正用于数据生产的Prompt,可能至少包含:任务定义、正例、反例、边界案例、优先级、输出格式、验收逻辑。一个项目100个人,如果100个人对这句话有100种理解,最后返工的就不是一个框,而可能是几十万帧数据。一个项目启动以后,项目经理先研究SOP,培训组长,组长再培训标注员,最后几百个人按照同一套规则干活。实际上一个成熟的项目经理,最重要的能力之一,就是:把客户的业务语言翻译成生产规则。真正让项目难交付的,从来不是80%的普通数据,而是那20%的长尾数据。

AI数据标注猿 295

Effecective STL: 容器 (条款1: 小心选择你的容器)

Effecective STL: 容器 (条款1: 小心选择你的容器) [缘起] 最近一直在学习STL,从《C++标准库(The C++ Standard Library)》到《STL 源码剖析》再到《泛型编程与STL(Generic Programming and the STL)》,自认为对STL有一定认识。为了让自己有进一步的提高,试着翻译这部《Effective STL》,错误再所

ttx2003的专栏 1099

(8)(8.19) GPIOs

Ardupilot官网关于《Copter》的翻译 —《(8.19) GPIOs》。

无人机开发(开源Ardupilot) 1万+

yolov8涨点系列之替换幽灵卷积GhostConv

yolov8涨点系列之替换幽灵卷积GhostConv

zhang1379的博客 3564

学习Effective STL——仔细选择你的容器

这几天,稍有空闲,于是看了一下《Effective STL》一书,非常经典的一本书~学到了不少的新知识~也记录一下一些重要的内容点~加深印象~     条款一:仔细选择你的容器。     标准STL序列容器:vector, string, deque, list;   标准STL关联容器:set, multiset, map, multimap;   非标准序列容器:  slist(单向链表),

FOREVER_MOUSE_123的专栏 696

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Effective STL 中文版(大全)

候捷说,对于STL,程序员有三个境界,开始是使用STL,然后是理解STL,最后是补充STL。EffectiveSTL是一本非常好的书,帮助你更好的理解STL,其作者就是《EffectiveC++》一书的作者。如果你已经初步了解了STL的容器、迭代器、算法和函数,而又想更好的了解STL,那么《EffectiveSTL》是你的最佳选择。 还有一部分没有找到链接,如果再找不到我会自己试着翻译

幸福村的人 1139

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Effective STL 条款45

STL搜索算法的区别[1]你要寻找什么,而且你有一个容器或者你有一个由迭代器划分出来的区间——你要找的东西就在里面。你要怎么完成搜索呢?你箭袋中的箭有这些:count、count_if、find、find_if、binary_search、lower_bound、upper_bound和equal_range。面对着它们,你要怎么做出选择?简单。你能很快很容易地做到。能更快,更容易,更好。

AMin2001的专栏 5823

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Effective STL 条款2

条款 2: 小心对“容器无关代码”的幻想STL是建立在泛型之上的。数组泛化为容器,参数化了所包含的对象的类型。函数泛化为算法,参数化了所用的迭代器的类型。指针泛化为迭代器,参数化了所指向的对象的类型。这只是个开始。独立的容器类型泛化为序列或关联容器,而且类似的容器拥有类似的功能。标准的内存相邻容器(参见条款1)都提供随机访问迭代器,标准的基于节点的容器(再参见条款1)都提供双向迭代器。序列

AMin2001的专栏 1651

2 Studying《Effective STL》

《Effective STL》摘要 STL是C++标准库的重要组成部分,涵盖容器、迭代器、算法和函数对象等。本文总结了STL使用中的关键要点: 容器选择: 根据插入删除位置选择序列容器(vector、list、deque) 考虑查找效率选择关联容器(set、map)或哈希容器 指针容器需注意资源管理,建议使用智能指针 容器操作优化: 优先使用empty()而非size()==0 区间操作比单元素操作更高效 使用reserve避免频繁重新分配内存 注意string实现的多样性 算法使用: 确保目标区间足够大

u012906122的专栏 753

Effective STL 条款30

条款30:确保目标区间足够大STL容器在被添加时(通过insert、push_front、push_back等)自动扩展它们自己来容纳新对象。这工作的很好,有些程序员因为这个信仰而被麻痹,认为他们不必担心要为容器中的对象腾出空间,因为容器自己可以照顾好这些。如果是那样就好了!当程序员想向容器中插入对象但并没有告诉STL他们所想的时,问题出现了。这是一个常见的可以自我表现的方法:int

AMin2001的专栏 1761

Effective STL 条款18

Item18避免使用vector 做为一个STL容器,vector有两个问题.第一,它不是一个真正STL容器,第二,它并不保存bool类型.除此以外,并没有太多东西与本节题目有关(译注,还不够多吗)一个东西不能成为一个STL容器,只因为会有人说它是一个(译注,:( ).一个东西要成为STL容器,必须满足所有列于C++标准23.1节的容器要求.在这些要求中,有这样一条:如果C是一个T类型元素容器

solotony的专栏 1674

Effective STL 目录

由于没有看内容,有些翻译可能不准确,请见谅:)容器条款1: 仔细选择你要的容器 条款2: 小心对“容器无关代码”的幻想 条款3: 使容器里对象的拷贝操作轻量而正确 条款4: 用empty来代替检查size是否为0 条款5: 尽量使用范围成员函数代替他们的单元素兄弟 条款6: 警惕C++的及其令人恼怒的分析 条款7: 当使用new得指针的容器时,切记在容器销毁前d

AMin2001的专栏 1483

Effective STL 条款32

条款32:如果你真的想删除东西的话就在类似remove的算法后接上erase 我将从remove的复习开始这个条款,因为remove是STL中最糊涂的算法。误解remove很容易,驱散所有关于remove行为的疑虑——为什么它这么做,它是怎么做的——是很重要的。 这是remove的声明: templateForwardIterator remove(ForwardIterato

AMin2001的专栏 1685
上一篇: Cg In Two Pages
下一篇: Effective STL 条款3
AMin2001
博客等级 码龄26年 7粉丝 35原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值