C++ / a working model

BOOK / SOURCE & READING RECORD

STL 源码剖析 / The Annotated STL Sources

侯捷;附录 C:孟岩

华中科技大学出版社,2002 年第一版,ISBN 7-5609-2699-1;研究副本为 534 页扫描,正文印刷页 1–494。

READING EVIDENCE / Full text read

STL 源码剖析 / The Annotated STL Sources

The text of Chapters 1–8, Appendices A–C, and the index was actually read page by page (PDF pages 34–527, printed pages 1–494), and all identified important figures and code points of doubt were examined directly. Chapters 1–6 were recorded in a divided reading report; Chapters 7–8 and the appendices were completed by the primary reader. Historical implementation errors are distinguished separately; this does not claim that all code in the book was executed. Other books recommended in the appendices are not thereby counted as having been read.

Edition, actual reading range, and original sources →

Sources

From storage to objects, then to algorithm contracts

Chapter 2, printed pages 43–78; Chapter 4, vector/list construction and memory management.

This book places allocators before containers not to require that everyday applications hand-write memory pools, but so that readers first distinguish storage, object lifetime, and exception cleanup. Obtaining a sufficiently large block of memory does not mean assignable objects already exist in it; when construction fails midway, one must distinguish the already-constructed portion from unused space. This distinction then runs through vector reallocation, linked-list node creation, and uninitialized-range algorithms. When reading today, keep this causal chain, but do not treat the old implementation’s 8-byte bins, 128-byte threshold, or POD fast path as standard guarantees. Modern alignment, implicit-lifetime rules, move semantics, and allocator_traits all need to be checked separately; understanding one implementation does not yield the contracts of all implementations.

Capabilities, representation, and invalidation must be judged separately

Chapter 3, printed pages 79–112; Chapter 4; Chapter 8 §8.3, printed pages 435–447.

Iterators let algorithms depend on operational capabilities without needing to know how the container stores elements; traits and tag dispatch turn capability differences into different implementation paths. A contiguous array can jump by computing a distance, a linked list must move node by node, and a segmented deque must convert between buffers and the map of indices. They offer similar expressions but do not share the same complexity or invalidation rules. When reading source, especially do not promote “this version’s iterator is a pointer” into a portable interface. Output adapters are also not positions of already-existing elements: assigning to a back_inserter actually performs push_back. Conversely, reserve only prepares capacity; it does not make begin() of an empty vector a valid output destination.

Historical implementations need to be cross-read against the modern standard

Chapter 6 §6.7; Chapter 7, printed pages 413–424; Chapter 8, printed pages 425–460.

This book retains its value for understanding SGI STL, and also retains old interfaces and a few inaccurate statements. Sorting requires a strict weak ordering; it does not require that the comparator be true for every pair of adjacent elements—duplicate keys especially reveal this distinction. for_each ignores the return value, yet can modify contents through writable element references; calling it broadly “unable to modify elements” misleads readers. A reverse iterator’s base is after the referred-to element; neither end nor rend is dereferenceable; dangerous output on the book’s pages cannot become a runtime guarantee. Old bind2nd, ptr_fun, and mem_fun can today be expressed with lambdas, mem_fn, and invoke, but updating the interface does not waive responsibilities for lifetime, output space, and call arity.

Related fundamentals

Iterators: capability categories, ranges, and validityAlgorithms: sort, boundary search, and erase-removeAllocator and pmr: choosing a resource and its lifetimeLambda capture: a closure is an object with a lifetime

Original practice →