BOOK / SOURCE & READING RECORD
STL 源码剖析 / The Annotated STL Sources
侯捷;附录 C:孟岩
华中科技大学出版社,2002 年第一版,ISBN 7-5609-2699-1;研究副本为 534 页扫描,正文印刷页 1–494。
STL 源码剖析 / The Annotated STL Sources
实际逐页读取第 1–8 章、附录 A–C 与索引的文字(PDF 34–527,印刷页 1–494),并直接查看全部已识别的重要图示及代码疑点。第 1–6 章由分工阅读报告记录,第 7–8 章与附录由主阅读者完成;历史实现错误另作区分,不声称执行了书中全部代码。附录中的其他书籍推荐不等于那些书也已经读完。
查看版本、实际阅读范围与原文入口 →Sources
公开扫描入口:STL 源码剖析
外部公开扫描入口,不是出版社授权镜像。本站研究记录按 2002 年版的印刷页定位;不同扫描可能有不同 PDF 页序。
研究副本不在本站公开链接。
- 编程指北:包含本书的 C++ 推荐书单
仅说明本书为何纳入此次 C++ 书单,不计作书籍正文阅读。
从存储到对象,再到算法契约
第 2 章,印刷页 43–78;第 4 章 vector/list 构造与内存管理。
这本书把分配器放在容器之前,不是要求日常应用都手写内存池,而是让读者先分清存储、对象生存期与异常清理。取得一块足够大的内存,不表示其中已经存在可赋值的对象;构造中途失败时,又必须区分已经完成构造的部分与尚未使用的空间。这个区分随后贯穿 vector 的重分配、链表的节点创建和未初始化区间算法。今天阅读时应保留这条因果链,却不把旧实现的 8 字节分级、128 字节阈值或 POD 快速路径当成标准保证。现代对齐、隐式生存期规则、移动语义和 allocator_traits 都需要另行核对;看懂一份实现不等于得到所有实现的契约。
能力、表示和失效必须分别判断
第 3 章,印刷页 79–112;第 4 章;第 8 章 §8.3,印刷页 435–447。
迭代器让算法依赖操作能力,而不必知道容器怎样保存元素;traits 与标签分派则把能力差异转成不同实现路径。连续数组能用距离计算直接跳转,链表需要逐节点移动,分段 deque 又需要在缓冲区和索引表之间换算。它们提供相似表达式,却不拥有相同的复杂度与失效规则。阅读源码时尤其不能把“这个版本的 iterator 是指针”升级成可移植接口。输出配接器也不是已经存在的元素位置:向 back_inserter 赋值实际执行 push_back。相反,reserve 只准备容量,不会让空 vector 的 begin 成为合法输出目的。
历史实现需要与现代标准交叉阅读
第 6 章 §6.7;第 7 章,印刷页 413–424;第 8 章,印刷页 425–460。
本书保留了理解 SGI STL 的价值,也保留了旧接口与少量不准确表述。排序要求严格弱序,不要求所有相邻元素都满足比较器为真,重复键尤其能揭示这个区别。for_each 忽略返回值,却可以通过可写元素引用修改内容;把它笼统称为“不能修改元素”会误导读者。反向迭代器的 base 位于所指元素之后,end 和 rend 都不可解引用;书页中的危险输出不能成为运行保证。旧式 bind2nd、ptr_fun 和 mem_fun 今天可用 lambda、mem_fn 与 invoke 表达,但接口更新并不免除生命周期、输出空间与调用元数的责任。
相关基础课
迭代器:能力类别、范围与有效性算法:sort、边界查找与 erase-removeAllocator 与 pmr:资源选择和生命周期Lambda 捕获:闭包也是有生命期的对象