Effective STL学习

2023-11-02

引言

以下为个人的一些读书心得,对于部分比较浅显易懂的就不再赘述,只是日常使用中不太会留意到的加以解释。

第一章 容器

第一条:慎重选择容器类型

第二条:不要试图编写独立于容器类型的代码

第三条:确保容器中的对象拷贝正确而高效

第四条:调用empty而不是检查size()是否为0

举例:list的size()可能需要遍历整个链表才能得到,而empty却不需要。

第五条:区间成员函数优先于与之对应的单元素成员函数

比较三种形式:
1.

v1.assign(v2.begin() + v2.size()/2, v2.end());

2.

vector<Widget> v1, v2;
...
v1.clear();
for (vector<Widget>::const_iterator ci = v2.begin() + v2.size()/2; ci!= v2.end(); ++ci) {
    v1.push_back(*ci);
}

3.

vector<Widget> v1, v2;
...
v1.clear();
copy(v2.begin() + v2.size() / 2, v2.end(), back_inserter(v1));

比较三种形式,2,3比较类似(3的内部实现几乎和2相同,故合并讨论,仅讨论1和2的区别)。
书中讲了三点:a.多次对insert的调用(这个我认为几乎可以忽略);b.针对于当前例子,针对v1多次的push_back可能导致vector容量多次增加,而通过区间成员函数会一次性增加到所需容量;c.insert或者push_front比较明显,每次调用均会导致后面内容的移动,而通过区间成员函数几乎总可以一次性移动到位。

最后书中给出了几种区间函数:
1. 区间创建 container::container(InputIterator begin, InputIterator end);
2. 区间插入 void container::insert(iterator position, InputIterator begin, InputIterator end);
3. 区间删除 iterator container::erase(iterator begin, iterator end);// 序列容器 void container::erase(iterator begin, iterator end);// 关联容器 // 这些不同导致在循环中删除容器元素的区别,在后面条例中也有提及,这里支出关联容器不返回一个迭代器是由于这样操作将导致不可接受的性能负担,对此作者也不甚赞同。
4. 区间赋值 void constainer::assign(InputIterator begin, InputIterator end);

第六条:当心c++编译器最烦人的分析机制

ifstream dataFile("ints.dat");
list<int> data(istream_iterator<int>(dataFile), istream_iterator<int>());

虽然这段代码当使用到data时即会报错,但是还是可以分析下以上代码被解析的语义:
istream_iterator(dataFile), istream_iterator()将被解析为两个参数(第一个参数名为dataFile,第二个参数名进行了省略);
类似:int f(double (d)); <==> int f(double d);
最终可以将istream_iterator(dataFile)通过“()”包裹即可

第七条:如果容器中包含了通过new操作创建的指针,切记在容器对象析构钱江指针delete掉

第八条:切勿创建包含auto_ptr的容器对象

第九条:慎重选择删除元素的方法

以下附上了书中的总结,其中第三条需要注意下,这个也可以参见条例五区间删除。
这里写图片描述

第十条:了解分配子的约定和限制

这条在定制allocator时需要注意

第十一条:理解自定义分配子的合理用法

第十二条:切勿对STL容器的线程安全性有不切实际的依赖

第二章 vector和string

第十三条:vector和string优先于动态分配的数组

第十四条:使用reserve来避免不必要的重新分配

第十五条:注意string实现的多样性

//TODO 有空可以多查看下各种知名的实现,或者参照书中提出的自己实现一下

第十六条:了解如何把vector和string数据传给旧的API

  1. vector传递给指针: &vd[0],vector在c++标准中保证了它和数组内存上保持一致(注意不要使用vd.begin(),因为没有强制要求vector迭代器的就采用指针实现);
  2. string s; s.c_str();
  3. string,set,list需要采用c api均可以通过vector传递,在通过assign进行转换。(注意:vector通过c api填充值后需要重新resize
    这里写图片描述

第十七条:使用“swap技巧”出去多余容量

// 使容量最小
vector<Contestant> v;
string s;
...
vector<Contestant>(v).swap(v);
string(s).swap(s);
// 清空并使容量最小
vector<Contestant> v;
string s;
...
vector<Contestant>().swap(v);
string().swap(s);

第十八条:避免使用vector

由于vector进行了优化,内部使用bit进行存储,所以vector::operator[]返回和其它vector有所不同,书中建议避免使用,本人对此知识有限,当遇到它的弊端再详细探讨。

第三章 关联容器

第十九条:理解相等和等价的区别

这个主要对于关联容器中的插入,因为关联容器要要排序(考虑set),插入一个对象,总能考虑是在参考节点前面还是在后面(这种通过operator<或者是用户定义的判别式进行判断),如果a,b: a < b == false && b < a == false则a、b等价,则ab不能同时插入进set,所以是否等价为插入的唯一标准
但有时候等价和相等并不一致:如果set中插入元素判别式不区分大小写,而元素相等需要精确匹配。则A、a不能同时插入进set,而且set的find采用等价规则(注意和std ::find采用相等规则,两者可能出现不太一致的现象),举例:
这里写图片描述

第二十条:为包含指针的关联容器指定比较类型

今天到此为止,后期继续添加

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Effective STL学习 的相关文章

  • 如何查找boost运行时版本

    我正在编写一个使用 boost 的 C 库 在这个库中 我想包含有关用于编译我的库的二进制版本的 boost 版本的信息 我可以使用宏BOOST VERSION这很好 我还想确定哪个是 boost 的运行时版本 以便我可以与用于编译我的库的
  • 加权 Voronoi 的 CGAL 2D APOLLONIUS 图 - 如何生成和获取面和顶点?

    我正在尝试根据阿波罗尼乌斯图生成加权沃罗诺伊 我正在使用 CGAL 库 我找不到如何从 apollonius 获取面和顶点的好例子 我有以下类型定义 typedef double NT typedef CGAL Cartesian lt N
  • 线程安全的get(访问器方法)

    我目前正在使用以下代码对变量进行线程安全访问 int gnVariable void getVariableValue int pnValue acquireLock Acquires the protection mechanism pn
  • 如何使用Task.WhenAny并实现重试

    我有一个创建多个基于 I O 的任务的解决方案 我正在使用Task WhenAny 来管理这些任务 但通常许多任务会由于网络问题或请求限制等原因而失败 我似乎找不到一个解决方案 使我能够在使用时成功重试失败的任务Task WhenAny 方
  • Reflection.Emit 中的短格式操作码错误

    我正在制作一种与以下非常相似的小语言hlsl但仅支持像素着色器 该语言使用reflection emit构建实现相同功能的 NET 程序集 我目前正在测试分支指令的实现if在我的一个单元测试中 一个大的if与内if elses 失败并显示以
  • 无法使用 ASP.NET Core 从 JWT 令牌获取声明

    我正在尝试使用 ASP NET Core 实现 JWT 持有者身份验证的非常简单的实现 我从控制器返回的响应有点像这样 var identity new ClaimsIdentity identity AddClaim new Claim
  • 将 try_emplace 与 shared_ptr 一起使用

    所以我有一个std unordered map
  • 在 C++ 中,严格别名规则中的“访问”是什么意思?

    3 10 10 说 如果一个程序试图access通过除以下类型之一之外的泛左值存储对象的值 行为未定义 然而 术语 访问 并没有在任何地方定义 在这种情况下这意味着read or 读取或修改 在 C 标准中 它被明确定义为读取或修改 然而在
  • 尝试将元素推入向量

    在头文件 我没有编写 中 已经定义了一个结构体 如下所示 struct MemoryMessage public boost counted base public FastAlloc explicit MemoryMessage Memo
  • 使用 C 创建立体声正弦波

    我正在尝试用 C 创建立体声正弦 WAV 并且可能有不同的 可能是空白的 左声道和右声道 使用此函数为每个通道生成一个音调 int16 t create tone float frequency float amplitude float
  • 我应该使用函数还是无状态函子?

    这两段代码做同样的事情 如您所见 它将用于排序函数 哪个更好 我通常写后一种 但我看到一些程序员像以前那样做 struct val lessthan binary function
  • C++ 克隆惯用语中协变返回类型的用处?

    通常的克隆习惯使用协变返回类型 struct Base virtual Base clone struct Derived public Base Derived clone 我读过一些内容 大意是协变返回类型是 C 后来添加的 较旧的编译
  • 标准头文件中的 C 编译器错误 - 未定义的 C++ 定义

    我正在尝试编译 C 程序 但收到许多错误 这些错误是在标准 C 头文件 inttypes h stdio h stat h 等 中遇到的 错误的来源是以下未定义的常量 BEGIN DECLS END DECLS BEGIN NAMESPAC
  • 允许 .NET WebApi 忽略 DOCTYPE 声明

    我正在尝试通过 WebApi 方法将 XML 反序列化为对象 我有以下课程 XmlRoot IsNullable false public class MyObject XmlElement Name public string Name
  • 读取所有进程内存以查找字符串变量c#的地址

    我有 2 个用 C 编写的程序 第一个名为 ScanMe 的程序包含一个包含值 FINDMEEEEEEE 的字符串变量 以及一个值为 1546 22915487 的双精度变量 另一个名为 MemoryScan 的程序读取第一个程序的所有内存
  • 如何在 Xamarin.Mac 中执行终端命令并读入其输出

    我们正在编写一个 Xamarin Mac 应用程序 我们需要执行像 uptime 这样的命令 并将其输出读取到应用程序中进行解析 这可以做到吗 在 Swift 和 Objective C 中都有 NTask 但我似乎无法在 C 中找到任何示
  • #define, #ifdef #undef #endif

    我有以下代码 define PROC ADD void main void while 1 ifdef PROC ADD Do this code here then undefined it to run the code in the
  • Yield Return == IEnumerable 和 IEnumerator 吗?

    Is yield return实施的捷径IEnumerable and IEnumerator 是的 您可以在我的书 C in Depth 的第 6 章中找到更多相关信息 幸好第六章是免费提供 http www manning source
  • lambda 表达式是多线程的吗?

    lambda 表达式是多线程的吗 假设当你将数学公式编写为 lambda 方法时 当你将其传递给另一个方法时 它会是多线程的吗 不是100 清楚你问的是什么 您是否想问 lambda 是否自然地在不同的线程上运行 如果是这样 则它们只是 S
  • 组合框由于某种原因被链接

    我有以下代码来填充 3 个组合框 private void PopulateDDLs SqlConnection connection SqlCommand command SqlDataReader reader DataTable dt

随机推荐

  • 华为交换机SSH登录失败原因

    解决方案 SSH登录失败几种常见原因 1 配置错误 例如设备没有开启STelnet服务功能等 处理方法 参考 配置通过STelnet登录设备示例 检查配置是否正确和完整 2 设备作为SSH服务器 协议版本号高于客户端的协议版本号 版本不一致
  • 轻松学会网络编程

    目录 一 UDP 和 TCP 特点对比 1 有连接和无连接 2 可靠传输和不可靠传输 3 面向字节流和面向数据报 4 全双工和半双工 二 UDP 的 socket api 1 DatagramSocket 2 DatagramPacket
  • LeetCode第55题:跳跃游戏:给定一个非负整数数组 nums ,你最初位于数组的 第一个下标 。 数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标。

    LeetCode第55题 跳跃游戏 给定一个非负整数数组 nums 你最初位于数组的 第一个下标 数组中的每个元素代表你在该位置可以跳跃的最大长度 判断你是否能够到达最后一个下标 示例 输入 nums 2 3 1 1 4 输出 true 解
  • SpringBoot配置Mybatis的两种方式(通过XML配置和通过YML配置文件配置)

    一 通过XML的方式配置Mybatis 在 src main resource下创建Mybatis配置文件 mybatis config xml 和 映射文件目录mapper 在application yml指定Mybatis配置文件 映射
  • 优化算法——全局灵敏度分析算法(PAWN )(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 目前更新 电力系统相关知识 期刊论文 算法 机器学习和人工智能学习 支持 如果觉得博主的文章还不错或者您用得到的话 可以关注一下博主 如果三连收藏支持就更好啦 这就
  • Ceph入门到精通-ceph对于长文件名如何处理

    RADOS object with short name 上一篇博文 我们将介绍了对象相关的数据结构ghobject t 以及对象在底层文件系统存储的文件名 以及如何从文件名对应到 ghobject t对象 映射关系如下图所示 这里面有一个
  • [QT编程系列-27]:多线程机制 - 信号与槽实现不同对象之间通信的五种情形:线程内同步通信、线程内异步通信、线程间异步通信

    目录 理论基础 0 1信号与槽机制 0 2 线程的事件队列 0 3 线程的信号队列 第1种情形 主线程上下文的两个对象之间同步通信 第2种情形 主线程上下文的两个对象之间异步通信 第3种情形 子线程给主线程上下文中的对象发送异步信号 第4种
  • 香港一事无成一日游

    因工作需求 我想开一些港卡 跟老婆商量后 说办就办 参考了群友和前同事的开卡相关的经验文章 再结合小红书上的各种教程 准备去香港将此事解决 因为不太懂里面的道道 我们自己也准备了一份自认为比较周全的文档 此文档结众家之长 在出发前 文档创建
  • 关于单链表的增删查改等操作(c语言版)

    目录 1 关于单链表 2 单链表的优缺点 3 单链表的初始化 4 申请新结点 5 关于单链表的插入 尾插 6 单链表的头插 7 单链表的尾删 7 单链表的头删 8 单链表的查找 9 在某一的数字的前面插入新数据 10 在某一结点之后插入数据
  • windows10 安装mqtt服务器和client客户端进行本地调试

    一 安装mqtt服务器 使用emqx作为mqtt服务器 下载emqx windows 4 3 8 zip emqx windows 4 3 8 zip 其他版本 Directory listing for broker EMQ 解压到自定义
  • 微信小程序压缩wxml

    背景 微信小程序添加webpack压缩之后 支持js css等压缩 但是wxml没有找到对应的api 后来看到小程序可以启动自定义编译命令 兜兜转转找到了一些命令来实现wxml的压缩 记录如下 需要的伙伴自取 命令输入位置如下图 命令如下
  • 安装教程rtx2080ti_Ubuntu18.04上安装RTX 2080Ti显卡驱动

    上了RTX 2080Ti显卡后 原来Ubuntu18 04内置的驱动和PPA安装的都不运作了 安装NVidia官网下载的驱动可以跑起来 但是需要费一些周折 1 禁用系统默认显卡驱动 打开系统黑名单 sudo gedit etc modpro
  • 网页游戏《天书世界》屌丝修仙记

    天书世界修仙 无限小号刷打宝塔 得到的金钱数据对比 终极玩法 天书世界 修仙 看了一些玄幻修仙小说 主人公屌丝逆袭白富美的攻略只有一个 就是不同常人的隐藏技能 作为工程师 羡慕没鸟用 还是实践一下 看看是否有潜质 于是搞了一个网页游戏 耍耍
  • JAVA面试题汇总

    JAVA面试题汇总 一 java基础篇 1 final 关键字的作用 被 final 修饰的类不可以被继承 被 final 修饰的方法不可以被重写 被 final 修饰的变量不可以被改变 如果修饰引用 那么表示引用不可变 引用指向的内容可变
  • Mybatis中的statementType="STATEMENT"使用注意

    今天遇到如下问题 Cause com mysql jdbc exceptions jdbc4 MySQLSyntaxErrorException You have an error in your SQL syntax check the
  • vulnhub靶场 DC-1

    过程曲曲折折 中途还看了下题解才断断续续的完成这个靶场 只能说技术不到家 攻击机 kali ip 192 168 16 134 靶场 ip 192 168 16 149 首先是到vulnhub官网去下载DC 1的靶场这里就不讲如何下载了 直
  • 【100天精通python】Day34:使用python操作数据库_ORM(SQLAlchemy)使用

    目录 专栏导读 1 ORM 概述 2 SQLAlchemy 概述 3 ORM SQLAlchemy使用 3 1 安装SQLAlchemy 3 2 定义数据库模型类 3 3 创建数据表 3 4 插入数据 3 5 查询数据 3 6 更新数据 3
  • SpringBoot 系统全局异常处理

    1 编写系统全局异常处理类要求 1 定义全局异常处理类 使用 ControllerAdvice 注解标签修饰 2 处理指定异常类信息 通过 ExceptionHandler 注解标签修饰 3 处理指定异常类是否向前端返回错误信息 如果需要向
  • Restful API 的设计规范

    Restful API 的设计规范 Restful API 的设计规范 1 URI URI规范 资源集合 vs 单个资源 避免层级过深的URI 对Composite资源的访问 2 Request HTTP方法 安全性和幂等性 复杂查询 Bo
  • Effective STL学习

    引言 以下为个人的一些读书心得 对于部分比较浅显易懂的就不再赘述 只是日常使用中不太会留意到的加以解释 第一章 容器 第一条 慎重选择容器类型 第二条 不要试图编写独立于容器类型的代码 第三条 确保容器中的对象拷贝正确而高效 第四条 调用e