C++ / a working model

BOOK / SOURCE & READING RECORD

The C++ Standard

ISO/IEC JTC 1/SC 22/WG 21

书单指定ISO/IEC 14882:2011;实际读取公开工作草案N3337(2012-01-16),不是正式ISO文本

READING EVIDENCE / Full text read

The C++ Standard

Fully read the HTML body of the public N3337 working draft, all 30 chapters and annexes A–E, including all visible code, grammar, requirement tables, notes, and footnotes. Chapters 1 and 15 were read by this agent; the remaining chapters were read continuously, section by section, by 7 shard readers with an exact ledger preserved; the SVG tags and edge relationships of the 7 figures were also read, without claiming screenshot verification. This “full” denotes only the complete text of the public N3337 draft; it does not mean the paid ISO/IEC 14882:2011 official publication was obtained or read through, nor does it include cited external standards.

Edition, actual reading range, and original sources →

Sources

Construction failure: the complete object is not destroyed, but members are still cleaned up

N3337 §15 in full, with emphasis on §15.2/1–3; §12.6.2/10; §12.4/8; §3.8 in full

The payoff of reading the standard is turning seemingly contradictory slogans into conditional rules. When object construction fails it is not that “nothing is destroyed”; an incomplete complete object differs from already-completed subobjects, and cleanup of the latter is exactly the basis on which resource handles can be composed. By logging the successful-construction path and the failure path, the standard's reverse-order rule can be turned into observable events without depending on stack layout or the exception implementation. Version must also be part of the conclusion: the publicly readable N3337 is a working draft after C++11, containing exception specifications and lifetime wording later deleted or rewritten; it cannot be labeled as the official ISO 2011 text, nor used to cover all of C++20's rules. This lesson focuses on one observable lifetime rule and does not let a single program stand in for the whole standard; the full-draft reading scope has a separate chapter-by-chapter ledger.

First distinguish a valid program, an unspecified choice, and a precondition violation

N3337 §1; §3; §17.3–17.6; §20.7; §23.2

The standard is not an implementation tutorial; it is a layered contract. The core language first specifies names, types, objects, and expressions; the library general provisions then specify acceptable types, call preconditions, return status, complexity, and exception guarantees. A moved-from object that is “valid but unspecified” can still perform operations that meet their preconditions; that is not the same as being freely indexable. An order the implementation may choose is also not the same as undefined behavior. Library requirements tables check more than whether an expression compiles; they also include semantics such as equivalence relations, ordering relations, and allocator interchange of storage. When reading a clause, keep both the applicable conditions and the guarantees in mind, rather than clipping a single conclusion out of context. Defects in a historical draft may also have been corrected later by errata; current compilers need not reproduce every detail of the old wording.

Lookup, candidate selection, and access checking have their own order

N3337 §3.4; §10.2; §11; §13.3; §14.6–14.8; figures 2–6

Name lookup first determines meaning and candidates; template deduction and substitution produce the declarations that may participate; overload rules then compare conversions on each argument; access control cannot help a program select a second-best function by discarding a private best match. “Best” for multiple parameters is a per-argument relation, not a sum of conversion costs. Name lookup in inheritance also has to track the set of declarations and the set of subobjects: a shared node of the same virtual base is not equivalent to two objects of a non-virtual repeated base. Reading the standard this way explains why another overload that seemed callable was not selected, and also avoids teaching two-phase lookup as a re-search of the whole world at instantiation time. C++20 constraints change the candidate mechanism and cannot be stuffed directly back into this draft.

Library abstractions isolate responsibility, not all risk

N3337 §21–30, with emphasis on §22.4, §24.2, §25.4.3, §27.5–27.8, §28.10, §30.4–30.6

Algorithms depend on iterator ranges rather than container ownership, so remove returns a logical end and an ordinary output iterator requires that the destination already have elements; character traits define sequence comparison, locale facets carry culture-specific rules, streambuf handles character transport, and the stream stores format and error bits. The concurrency library in turn separates thread handles, locks, condition predicates, and future shared state. Each layer has a composable interface and also leaves boundaries the caller must establish: the range is valid, borrowed data still exists, comparison satisfies the semantics, and a synchronization relationship is actually established. A binary search's logarithmic number of comparisons does not guarantee that a forward iterator takes only a logarithmic number of steps, and wrapping a regex result in an object does not give it ownership of the original text. These distinctions guide safe code better than memorizing class names.

Related fundamentals

Construction and destruction orderDestructors, exceptions, and noexceptRAII: Give Cleanup Responsibility to Objects

Original practice →