《C++标准库(第2版)》是全球C++经典专业参考书籍时隔12年,基于C++11标准的全新重大升级。标准库提供了一组公共类和接口,极大地拓展了C++语言核心功能。《C++标准库(第2版)》详细讲解了每一标准库组件,包括其设计目的和方法、复杂概念的剖析、实用而高效的编程细节、存在的陷阱、重要的类和函数,又辅以大量用C++11标准实现的实用代码范例。除覆盖全新组件、特性外,《C++标准库(第2版)》一如前版,重点着眼于标准模板库(STL),涉及容器、迭代器、函数对象以及STL算法。此外,《C++标准库(第2版)》同样关注lambda表达式、基于区间的for循环、move语义及可变参数模板等标准库中的新式C++编程风格及其影响。
第 2 版译序 xxi第 2 版序言 xxiii第 2 版致谢 xxiv第 1 版序言 xxv第 1 版致谢 xxvi1 关于本书1.1 缘起1.2 阅读前的必要基础1.3 本书风格与结构1.4 如何阅读本书1.5 目前发展情势1.6 范例代码及额外信息1.7 反馈2 C++ 及标准库简介2.1 C++ Standard 的历史2.1.1 C++11 Standard 常见疑问2.1.2 C++98 和 C++11 的兼容性2.2 复杂度与 Big-O 标记3 语言新特性3.1 C++11 语言新特性3.1.1 微小但重要的语法提升3.1.2 以 auto 完成类型自动推导3.1.3 一致性初始化(Uniform Initialization)与初值列(Initializer List)3.1.4 Range-Based for 循环3.1.5 Move 语义和 Rvalue Reference3.1.6 新式的字符串字面常量(String Literal)3.1.7 关键字 noexcept3.1.8 关键字 constexpr3.1.9 崭新的 Template 特性3.1.10 Lambda3.1.11 关键字 decltype3.1.12 新的函数声明语法(New Function Declaration Syntax)3.1.13 带领域的(Scoped) Enumeration3.1.14 新的基础类型(New Fundamental Data Type)3.2 虽旧犹新的语言特性3.2.1 基础类型的明确初始化(Explicit Initialization for Fundamental Type)3.2.2 main()定义式4 一般概念4.1 命名空间(Namespace)std4.2 头文件(Header File)4.3 差错和异常(Error and Exception)的处理4.3.1 标准的 Exception Class(异常类)4.3.2 异常类(Exception Class)的成员4.3.3 以 Class exception_ptr 传递异常4.3.4 抛出标准异常4.3.5 自标准异常类派生4.4 Callable Object(可被调用的对象)4.5 并发与多线程4.6 分配器(Allocator)5 通用工具5.1 Pair 和 Tuple5.1.1 Pair5.1.2 Tuple(不定数的值组)5.1.3 Tuple 的输入/输出5.1.4 tuple 和 pair 转换5.2 Smart Pointer(智能指针)5.2.1 Class shared_ptr5.2.2 Class weak_ptr5.2.3 误用 Shared Pointer5.2.4 细究 Shared Pointer 和 Weak Pointer5.2.5 Class unique_ptr5.2.6 细究 Class unique_ptr5.2.7 Class auto_ptr5.2.8 Smart Pointer 结语5.3 数值的极值(Numeric Limit)5.4 Type Trait 和 Type Utility5.4.1 Type Trait 的目的5.4.2 细究 Type Trait5.4.3 Reference Wrapper(外覆器)5.4.4 Function Type Wrapper(外覆器)5.5 辅助函数5.5.1 挑选最小值和最大值5.5.2 两值互换(Swapping)5.5.3 增补的"比较操作符"(Comparison Operator)5.6 Class ratio<> 的编译期分数运算5.7 Clock 和 Timer5.7.1 Chrono 程序库概观5.7.2 Duration(时间段)5.7.3 Clock(时钟)和 Timepoint(时间点)5.7.4 C 和 POSIX 提供的 Date/Time 函数5.7.5 以计时器停滞线程(Blocking with Timer)5.8 头文件 <cstddef>、<cstdlib> 和 <cstring>5.8.1 <cstddef> 内的各项定义5.8.2 <cstdlib> 内的各种定义5.8.3 <cstring> 中的定义式6 标准模板库6.1 STL 组件(Component)6.2 容器(Container)6.2.1 序列式容器(Sequence Container)6.2.2 关联式容器(Associative Container)6.2.3 序容器(Unordered Container)6.2.4 关联式数组(Associative Array)6.2.5 其他容器6.2.6 容器适配器(Container Adapter)6.3 迭代器(Iterator)6.3.1 关联式( Associative )及序 ( Unordered )容器的更多实例6.3.2 迭代器种类(Iterator Category)6.4 算法(Algorithm)6.4.1 区间(Range)6.4.2 处理多重区间(Multiple Ranges)6.5 迭代器之适配器(Iterator Adapter)6.5.1 Insert Iterator(安插型迭代器)6.5.2 Stream Iterator(串流迭代器)6.5.3 Reverse Iterator(反向迭代器)6.5.4 Move Iterator(搬移迭代器)6.6 用户自定义的泛型函数(User-Defined Generic Function)6.7 更易型算法(Manipulating Algorithm)6.7.1 移除(Removing)元素6.7.2 更易 Associative(关联式)和 Unordered(序)容器6.7.3 算法 vs. 成员函数6.8 以函数作为算法的实参6.8.1 以函数作为算法实参的实例示范6.8.2 判断式(Predicate)6.9 使用 Lambda6.10 函数对象(Function Object)6.10.1 定义一个函数对象6.10.2 预定义的函数对象6.10.3 Binder6.10.4 函数对象 vs. Lambda6.11 容器内的元素6.11.1 容器元素的必要条件6.11.2 Value 语义 vs. Reference 语义6.12 STL 内部的错误和异常6.12.1 错误处理(Error Handling)6.12.2 异常处理(Exception Handling)6.13 扩展 STL6.13.1 整合更多 Type6.13.2 派生自 STL Type7 STL 容器7.1 容器的共通能力和共通操作7.1.1 容器的共通能力7.1.2 容器的共通操作7.1.3 容器提供的类型7.2 Array7.2.1 Array 的能力7.2.2 Array 的操作7.2.3 把array当成 C-Style Array7.2.4 异常处理( Exception Handling )7.2.5 Tuple 接口7.2.6 Array 运用实例7.3 Vector7.3.1 Vector 的能力7.3.2 Vector 的操作7.3.3 将 Vector 当作 C-Style Array 使用7.3.4 异常处理( Exception Handling )7.3.5 Vector 使用实例7.3.6 Class vector<bool>7.4 Deque7.4.1 Deque 的能力7.4.2 Deque 的操作函数7.4.3 Exception Handling7.4.4 Deque 运用实例7.5 List7.5.1 List 的能力7.5.2 List 的操作7.5.3 异常处理( Exception Handling )7.5.4 List 运用实例7.6 Forward List7.6.1 Forward List 的能力7.6.2 Forward List 的操作7.6.3 异常处理( Exception Handling )7.6.4 Forward List 运用实例7.7 Set 和 Multiset7.7.1 Set 和 Multiset 的能力7.7.2 Set and Multiset 的操作函数7.7.3 异常处理( Exception Handling )7.7.4 Set 和 Multiset 运用实例7.7.5 运行期指定排序准则7.8 Map 和 Multimap7.8.1 Map 和 Multimap 的能力7.8.2 Map 和 Multimap 的操作函数7.8.3 将 Map 视为关联式数组( Associative Array )7.8.4 异常处理( Exception Handling )7.8.5 Map 和 Multimap 运用实例7.8.6 综合实例:运用 Map、 String 并于运行期指定排序准则7.9 序容器( Unordered Container )7.9.1 Unordered 容器的能力7.9.2 创建和控制 Unordered 容器7.9.3 Unordered 容器的其他操作7.9.4 Bucket 接口7.9.5 使用 Unordered Map 作为 Associative Array7.9.6 异常处理( Exception Handling )7.9.7 Unordered 容器的运用实例7.10 其他 STL 容器7.10.1 String 作为一种 STL 容器7.10.2 C-Style Array 作为一种 STL 容器7.11 实现 Reference 语义7.12 各种容器的使用时机8 细探 STL 容器成员8.1 容器内的类型8.2 创建、复制和销毁( Create, Copy, and Destroy )8.3 非更易型操作( Nonmodifying Operation )8.3.1 大小相关操作( Size Operation )8.3.2 元素比较( Comparison Operation )8.3.3 Associative 和 Unordered 容器特有的非更易型操作8.4 赋值( Assignment )8.5 元素直接访问( Direct Element Access )8.6 "产出迭代器"之各项操作8.7 安插和移除( Inserting and Removing )元素8.7.1 安插单一元素( Inserting Single Element )8.7.2 安插多重元素( Inserting Multiple Elements )8.7.3 移除元素( Removing Element )8.7.4 重设大小( Resizing )8.8 List 和 Forward List 的特殊成员函数8.8.1 特殊成员函数(针对 List 和 Forward List )8.8.2 特殊成员函数(只针对 Forward List )8.9 容器的策略接口( Policy Interface )8.9.1 非更易型策略函数( Nonmodifying Policy Function )8.9.2 更易型策略函数( Modifying Policy Function )8.9.3 Unordered 容器的 Bucket 相关接口8.10 对分配器( Allocator )的支持8.10.1 基本的分配器成员( Fundamental Allocator Member )8.10.2 带有"可选之分配器参数"的构造函数9 STL 迭代器9.1 迭代器头文件( Header Files for Iterators )9.2 迭代器种类( Iterator Category )9.2.1 Output 迭代器9.2.2 Input 迭代器9.2.3 Forward(前向)迭代器9.2.4 Bidirectional(双向)迭代器9.2.5 Random-Access(随机访问)迭代器9.2.6 Vector 迭代器的递增( Increment )和递减( Decrement )9.3 迭代器相关辅助函数9.3.1 advance()9.3.2 next()和prev()9.3.3 distance()9.3.4 iter_swap()9.4 迭代器适配器( Iterator Adapter )9.4.1 Reverse(反向)迭代器9.4.2 Insert(安插型)迭代器9.4.3 Stream(串流)迭代器9.4.4 Move(搬移)迭代器9.5 Iterator Trait(迭代器特性)9.5.1 为迭代器编写泛型函数( Generic Function )9.6 用户自定义( User-Defined )迭代器10 STL 函数对象及 Lambda10.1 Function Object(函数对象)的概念10.1.1 以 Function Object 为排序准则( Sorting Criterion )10.1.2 Function Object 拥有内部状态( Internal State )10.1.3 for_each()的返回值10.1.4 Predicate(判断式) vs. Function Object(函数对象)10.2 预定义的 Function Object 和 Binder10.2.1 预定义的 Function Object10.2.2 Function Adapter 和 Binder10.2.3 以 Function Adapter 搭配用户自定义的 Function Object10.2.4 过时的( Deprecated ) Function Adapter10.3 运用 Lambda10.3.1 Lambda vs. Binder10.3.2 Lambda vs. 带有状态的( Stateful ) Function Object10.3.3 Lambda 调用全局函数和成员函数10.3.4 Lambda 作为 Hash 函数、排序准则或相等准则11 STL 算法11.1 算法头文件(Header File)11.2 算法概观11.2.1 扼要介绍11.2.2 算法分门别类11.3 辅助函数11.4 for_each() 算法11.5 非更易型算法(Nonmodifying Algorithm)11.5.1 元素计数11.5.2 最小值和最大值11.5.3 查找元素(Searching Element)11.5.4 区间的比较11.5.5 Predicate 用以检验区间11.6 更易型算法(Modifying Algorithm)11.6.1 复制元素(Copying Element)11.6.2 搬移元素(Moving Element)11.6.3 转换和结合元素(Transforming and Combining Element)11.6.4 互换元素(Swapping Elements)11.6.5 赋值(Assigning New Value)11.6.6 替换元素(Replacing Element)11.7 移除型算法(Removing Algorithm)11.7.1 移除某些元素11.7.2 移除重复元素11.8 变序型算法(Mutating Algorithm)11.8.1 反转元素次序(Reversing the Order of Elements)11.8.2 旋转元素(Rotating Elements)11.8.3 排列元素(Permuting Elements)11.8.4 对元素重新洗牌(Shuffling Elements)11.8.5 将元素向前搬(Moving Elements to the Front)11.8.6 划分为两个子区间(Partition into Two Subranges)11.9 排序算法(Sorting Algorithm)11.9.1 对所有元素排序11.9.2 局部排序(Partial Sorting)11.9.3 根据第 {\itshape n} 个元素排序11.9.4 Heap 算法11.10 已序区间算法(Sorted-Range Algorithm)11.10.1 查找元素(Searching Element)11.10.2 合并元素(Merging Elements)11.11 数值算法(Numeric Algorithm)11.11.1 运算后产生结果11.11.2 相对数列和绝对数列之间的转换12 特殊容器12.1 Stack(堆栈)12.1.1 核心接口12.1.2 Stack 运用实例12.1.3 一个用户自定义的 Stack Class12.1.4 细究 Class stack<>12.2 Queue(队列)12.2.1 核心接口12.2.2 Queue 运用实例12.2.3 一个用户自定义的 Queue Class12.2.4 细究 Class queue<>12.3 Priority Queue(带优先级的队列)12.3.1 核心接口12.3.2 Priority Queue 运用实例12.3.3 细究 Class priority_queue<>12.4 细究 Container Adapter12.4.1 类型定义12.4.2 构造函数(Constructor)12.4.3 Priority Queue 额外提供的构造函数12.4.4 各项操作(Operation)12.5 Bitset12.5.1 Bitset 运用实例12.5.2 细究 Class bitset13 字符串13.1 String Class 的目的13.1.1 例一:提炼临时文件名13.1.2 例二:提炼单词并反向打印13.2 String Class 细节描述13.2.1 String 的各种相关类型13.2.2 操作函数概览13.2.3 构造函数和析构函数(Constructor and Destructor)13.2.4 String 和 C-String13.2.5 大小和容量(Size and Capacity)13.2.6 元素访问(Element Access)13.2.7 比较(Comparison)13.2.8 更改内容(Modifier)13.2.9 子字符串(Substring)及字符串接合(String Concatenation)13.2.10 I/O 操作符13.2.11 搜索和查找(Searching and Finding)13.2.12 npos 的意义13.2.13 数值转换(Numeric Conversion)13.2.14 String 对迭代器的支持13.2.15 国际化(Internationalization)13.2.16 效率(Performance)13.2.17 String 和 Vector13.3 细究 String Class13.3.1 类型定义和静态值13.3.2 创建、复制、销毁(Create, Copy, and Destroy)13.3.3 大小和容量(Size and Capacity)13.3.4 比较(Comparison)13.3.5 字符访问13.3.6 产生 C-String 和字符数组(Character Array)13.3.7 "改动"之相关操作(Modifying Operation)13.3.8 查找(Searching and Finding)13.3.9 子字符串(Substring)及字符串接合(String Concatenation)13.3.10 I/O函数13.3.11 数值转换(Numeric Conversion)13.3.12 生成 Iterator13.3.13 对 Allocator 的支持14 正则表达式14.1 Regex 的匹配和查找接口(Match and Search Interface)14.2 处理"次表达式"(Subexpression)14.3 Regex Iterator14.4 Regex Token Iterator14.5 用于替换的正则表达式14.6 Regex Flag14.7 Regex 的异常(Exception)14.8 Regex ECMAScript 文法14.9 其他文法14.10 细究 Basic Regex 签名式15 以 Stream 完成 I/O15.1 I/O Stream 的共通基础(Common Background)15.1.1 Stream 对象15.1.2 Stream Class15.1.3 全局的 Stream 对象15.1.4 Stream 操作符15.1.5 操控器(Manipulator)15.1.6 一个简单例子15.2 基本 Stream Class 和其对象15.2.1 Class 及其层次体系15.2.2 全局性的 Stream 对象15.2.3 头文件15.3 标准的 Stream 操作符 << 和 >>15.3.1 Output 操作符 <<15.3.2 Input 操作符 >>15.3.3 特殊类型的 I/O15.4 Stream 的状态(State)15.4.1 表示" Stream 状态"的常量15.4.2 用来"处理 Stream 状态"的成员函数15.4.3 Stream 状态与 Boolean 条件测试15.4.4 Stream 的状态和异常15.5 标准 I/O 函数15.5.1 Input 相关函数15.5.2 Output 相关函数15.5.3 实例15.5.4 sentry 对象15.6 操控器(Manipulator)15.6.1 操控器概览15.6.2 操控器如何运作15.6.3 用户自定义的操控器15.7 格式化(Formatting)15.7.1 Format Flag(格式标志)15.7.2 Boolean 的 I/O 格式15.7.3 栏位宽度、填充字符、位置调整15.7.4 正号与大写15.7.5 数值基底(Numeric Base)15.7.6 浮点数(Floating-Point)表示法15.7.7 一般格式(General Formatting)定义15.8 国际化(Internationalization)15.9 文件访问(File Access)15.9.1 File Stream Class15.9.2 File Stream 的 Rvalue 和 Move 语义15.9.3 File Flag(文件标志)15.9.4 随机访问(Random Access)15.9.5 使用文件描述器(File Descriptor)15.10 为 String 而设计的 Stream Class15.10.1 String Stream Class15.10.2 String Stream 的 Move 语义15.10.3 char* Stream Class15.11 "用户自定义类型"之 I/O 操作符15.11.1 实现一个 Output 操作符15.11.2 实现一个 Input 操作符15.11.3 以辅助函数完成 I/O15.11.4 用户自定义之 Format Flag(格式标志)15.11.5 用户自定义 I/O 操作符的规约(Convention)15.12 连接 Input 和 Output Stream15.12.1 以 tie() 完成松耦合(Loose Coupling)15.12.2 以 Stream 缓冲区完成紧耦合(Tight Coupling)15.12.3 将标准 Stream 重定向(Redirecting)15.12.4 可读可写的 Stream15.13 Stream Buffer Class15.13.1 Stream 缓冲区接口15.13.2 Stream 缓冲区的 Iterator15.13.3 用户自定义之 Stream 缓冲区15.14 关于效能(Performance)15.14.1 与 C 标准串流同步(Synchronization with C's Standard Streams)15.14.2 Stream 缓冲区内的缓冲机制15.14.3 直接使用 Stream 缓冲区16 国际化16.1 字符编码和字符集16.1.1 多字节(Multibyte)和宽字符(Wide-Character)文本16.1.2 不同的字符集16.1.3 在 C++ 中处理字符集16.1.4 Character Trait16.1.5 特殊字符的国际化16.2 Locale(地域)概念16.2.1 使用 Locale16.2.2 Locale Facet16.3 细究 Locale16.4 细究 Facet16.4.1 数值格式化(Numeric Formatting)16.4.2 货币符号格式化(Monetary Formatting)16.4.3 时间和日期格式化(Time and Date Formatting)16.4.4 字符的分类和转换16.4.5 字符串校勘(String Collation)16.4.6 消息国际化(Internationalized Message)17 数值17.1 随机数及分布(Random Number and Distribution)17.1.1 第一个例子17.1.2 引擎(Engine)17.1.3 细说引擎(Engine)17.1.4 分布(Distribution)17.1.5 细说分布(Distribution)17.2 复数(Complex Number)17.2.1 Class complex<> 一般性质17.2.2 Class complex<> 运用实例17.2.3 复数的各项操作17.2.4 细说 Class complex<>17.3 全局数值函数(Global Numeric Function)17.4 Valarray18 并发18.1 高级接口:async() 和 Future18.1.1 async() 和 Future 的第一个用例18.1.2 实例:等待两个 Task18.1.3 Shared Future18.2 低层接口:Thread 和 Promise18.2.1 Class std::thread18.2.2 Promise18.2.3 Class packaged_task<>18.3 细说启动线程(Starting a Thread)18.3.1 细说 async()18.3.2 细说 Future18.3.3 细说 Shared Future18.3.4 细说 Class std::promise18.3.5 细说 Class std::packaged_task18.3.6 细说 Class std::thread18.3.7 Namespace this_thread18.4 线程同步化与 Concurrency(并发)问题18.4.1 当心 Concurrency(并发)18.4.2 Concurrent Data Access 为什么造成问题18.4.3 什么情况下可能出错18.4.4 解决问题所需要的性质(Feature)18.5 Mutex 和 Lock18.5.1 使用 Mutex 和 Lock18.5.2 细说 Mutex 和 Lock18.5.3 只调用一次18.6 Condition Variable(条件变量)18.6.1 Condition Variable(条件变量)的意图18.6.2 Condition Variable(条件变量)的第一个完整例子18.6.3 使用 Condition Variable(条件变量)实现多线程 Queue18.6.4 细说 Condition Variable(条件变量)18.7 Atomic18.7.1 Atomic 用例18.7.2 细说 Atomic 及其高级接口18.7.3 Atomic 的 C-Style 接口18.7.4 Atomic 的低层接口19 分配器19.1 以应用程序开发者的角度使用 Allocator19.2 用户自定义的 Allocator19.3 以程序库开发者的角度使用 Allocator参考书目新闻组及论坛( Newsgroup and Forum )书籍和网站索引
我从未想过本书第1 版会卖得如此长久。现在,经过12 年的等待,出新版本的时候到了,一个涵盖最新C++11标准的新版本。 注意,其中的意义比仅仅添加新子库更多更大。C++ 已经改变了,其标准库的几乎所有典型应用如今看起来都有那么一点不同。这不是因为语言出现巨大变化,而是许多小改变造成的结果,例如运用rvalue reference 和move semantic、range-based 书乯乲loop、乡乵乴乯,以及新的template特性。因此,本书不但展现原标准库的补充特性及新成员,书中所有例子也都重新写过,或至少局部改写。尽管如此,为了支持那些仍然使用“旧” C++ 环境的程序员,本书会在遭遇C++版本差异时加以描述。 我学习C++11有一段艰难的历程。大约两年前我开始看C++11 但并未追随标准化的脚步,因此确实遭遇了理解上的麻烦。但是标准委员会的人帮助我描述及表现C++11 新特性,一如它们如今呈现的样貌。 最后,请注意,本书有个困扰:虽然份量上由800 页成长到超过1 100 页,我还是无法完整呈现C++ 标准库。标准库中单单针对C++11 就有大约750 页的描述,都是十分精练的文字,没有太多说明。基于这个原因,我必须取舍哪些特性需要描述,并决定以怎样的粒度描述之。再一次, C++ 社区中的许多人帮助我做出决定。我的企图集中在普通程序员需要的东西。若干本书舍弃的部分被我做成一份补充篇章放在本书官网乨乴乴买为丯丯乷乷乷丮乣买买乳乴乤乬乩乢丮乣乯乭。即便如此,你还是会在C++标准规格书中找到我未曾讨论的细节。 教学的艺术,并非体现在“呈现每一面”,而是一种“沙里淘金”的艺术,从中取得最大价值。但愿我是成功的。