第一部分 基础 2
第1章 标准模板库 2
1.1核心概念 2
1.2容器 2
1.2.1序列容器 2
1.2.2关联容器 3
1.2.3存储空间的连续性 3
1.2.4交换 3
1.3迭代器 3
1.3.1输入迭代器 4
1.3.2输出迭代器 5
1.3.3前向迭代器 5
1.3.4双向迭代器 5
1.3.5随机访问迭代器 6
1.3.6成员选取运算符 6
1.3.7预定义的迭代器适配器 7
1.4算法 8
1.5函数对象 8
1.6分配器 8
第2章 扩展STL:STL与真实世界的碰撞 10
2.1术语 10
2.2集合 10
2.3迭代器 12
2.3.1可变性 12
2.3.2遍历 12
2.3.3在编译期决定特性 12
2.3.4元素引用类别 12
2.3.5共享状态信息和独立状态信息 12
2.3.6需要修改迭代器精化的分类吗 13
第3章 元素引用类别 15
3.1介绍 15
3.2C++引用 15
3.3元素引用类别的分类法 16
3.3.1持久引用 16
3.3.2固定引用 17
3.3.3可失效引用 17
3.3.4瞬时引用 18
3.3.5按值临时引用 19
3.3.6空引用 20
3.4使用元素引用类别 20
3.4.1在编译时检测引用类别 20
3.4.2使用编译器帮助避免迭代器未定义行为 21
3.5定义operator->() 21
3.6元素引用类别:尾声 22
第4章 奇异去临时引用 23
第5章 DRYSPOT原则 24
5.1C++编程中符合DRYSPOT的做法 24
5.1.1常量 24
5.1.2dimensionof() 24
5.1.3创建函数 25
5.2C++编程中不太符合DRYSPOT的做法 25
5.2.1父类 25
5.2.2函数返回类型 26
5.3封闭的名字空间 27
第6章 抽象泄漏法则 28
第7章 契约式编程 29
7.1强制的类型 29
7.2强制的机制 30
第8章 约束 31
8.1利用C++类型系统 31
8.2静态断言 32
第9章 垫片 33
9.1介绍 33
9.2主要的垫片 33
9.2.1属性垫片 33
9.2.2转换垫片 34
9.3复合垫片 36
第10章 鸭规则和鹅规则:不完备结构一致性的发端 39
10.1一致性 39
10.1.1类型一致性 39
10.1.2结构一致性 40
10.1.3鸭规则和鹅规则 41
10.2显式语义一致性 42
10.2.1概念 42
10.2.2给成员类型打标签 43
10.2.3垫片 44
10.3交集一致性 44
第11章 资源获取即初始化 45
11.1资源可变性 45
11.2资源来源 45
第12章 模板工具 46
12.1特征类 46
12.1.1base_type_traits 47
12.1.2sign_traits 48
12.1.3类型的特性:迷你特征 49
12.1.4is_integral_type 49
12.1.5is_signed_type 50
12.1.6is_fundamental_type 51
12.1.7is_same_type 51
12.2类型生成器 52
12.3真正的typedef 52
第13章 推断式接口适配:编译时适配接口不全的类型 54
13.1介绍 54
13.2适配接口不全的类型 54
13.3适配非变动性集合 55
13.4推断式接口适配 56
13.4.1类型选择 57
13.4.2类型检测 57
13.4.3类型修正 58
13.5把IIA应用于区间 60
第14章 Henney假说:当模板参数表太长 61
第15章 通过equal()减少友元函数的使用 63
15.1警惕非成员友元函数的滥用 63
15.2集合及其迭代器 65
第16章 基本组件 66
16.1介绍 66
16.2auto_buffer 66
16.2.1它不是容器 66
16.2.2类接口 67
16.2.3复制 68
16.2.4分配器宜最后 68
16.2.5swap() 68
16.2.6性能 68
16.3filesystem_traits 69
16.3.1成员类型 69
16.3.2通用字符串处理 69
16.3.3文件系统名字处理 70
16.3.4文件系统状态操作 71
16.3.5文件系统控制操作 72
16.3.6返回类型和错误处理 72
16.4file_path_buffer 73
16.4.1basic 74
16.4.2UNIX和PATHMAX 74
16.4.3Windows和MAXPATH 75
16.4.4缓冲区的使用 76
16.5scoped_handle 76
16.6dlcall() 77
第二部分 集合 81
第17章 适配globAPI 81
17.1简介 81
17.1.1动机 81
17.1.2globAPI 82
17.2解析使用原始API的版本 84
17.3unixstl∷glob_sequence 86
17.3.1公有接口 86
17.3.2成员类型 87
17.3.3成员变量 87
17.3.4标志 88
17.3.5构造 90
17.3.6glob_sequence元素个数和元素访问 91
17.3.7迭代 91
17.3.8init_glob_() 92
17.4解析使用glob-sequence实现的版本 97
17.5小结 97
第18章 插曲:构造函数冲突以及不良的设计 99
第19章 适配opendir/readdirAPI 101
19.1介绍 101
19.1.1动机 101
19.1.2opendir/readdirAPI 102
19.2分析直接使用API的代码 103
19.3unixstl∷readdir_sequence 104
19.3.1成员类型和成员常量 105
19.3.2构造 106
19.3.3元素迭代和集合大小相关的方法 106
19.3.4提取属性的方法 107
19.3.5const_iterator,版本1 107
19.3.6使用版本1 111
19.3.7constiterator,版本2:复制语义 111
19.3.8operator++() 113
19.3.9迭代器类别和可适配的成员类型 114
19.3.10operator->() 114
19.3.11支持fullPath和absolutePath标志 115
19.4其他的实现方法 117
19.4.1把迭代结果保存为快照 117
19.4.2把迭代结果保存为迭代器 117
19.5总结 118
第20章 适配FindFirstFile/FindNextFileAPI 119
20.1介绍 119
20.1.1动机 119
20.1.2FindFistFile/FindNextFileAPI 121
20.2对例子的分解 123
20.2.1冗长版本 123
20.2.2精简版本 124
20.2.3重解析点和无限递归 124
20.3basic_findfile_sequence的设计 125
20.4winstl∷basic_findfile_sequence 125
20.4.1类的接口 126
20.4.2构造 128
20.4.3迭代 128
20.4.4如果编译器不支持异常 129
20.5winstl∷basic_findfile_sequence_const_iterator 131
20.5.1构造 132
20.5.2find_first_file_() 133
20.5.3operator++() 135
20.6winstl∷basic_findfile_sequence_value_type 141
20.7垫片 142
20.8basic_findfile_sequence为什么不用垫片和构造函数模板 143
20.9小结 143
20.10结尾:用recls进行文件系统遍历 144
第21章 插曲:枚举FTP服务器目录——保持效率和可用性的平衡 145
21.1inetstl∷basic_findfile_sequence 145
21.2inetstl∷basic_ftpdir_sequence 147
第22章 遍历进程和模块 149
22.1集合的特征 149
22.2winstl∷pid_sequence 149
22.2.1基于组合的简单实现 150
22.2.2获取进程ID 151
22.2.3没有异常支持时的工作方式 152
22.3winstl∷process_module_sequence 152
22.4枚举一个系统中的所有模块 153
22.5排除系统伪进程 154
22.6处理缺失API头文件的情况 155
22.7总结 156
第23章 斐波那契序列 157
23.1简介 157
23.2斐波那契序列 157
23.3STL序列表示的斐波那契数列 157
23.3.1无限序列的接口 159
23.3.2为序列添加契约 160
23.3.3换用别的值类型 160
23.3.4对值类型进行约束 160
23.3.5抛出std∷overflowerror 161
23.4可发现性的欠缺 161
23.5定义有限上界 162
23.5.1最终还是要用迭代器 162
23.5.2由构造函数限定的区间 163
23.5.3True_Typedefs 165
23.6小结 167
第24章 适配MFC的CArray容器族 168
24.1介绍 168
24.2动机 168
24.3模拟std∷vector 170
24.4设计时的考虑 171
24.4.1MFC的数组容器族 172
24.4.2CArray_traits 173
24.4.3数组适配器类的设计 174
24.4.4以抽象方式操纵状态 174
24.4.5Copy-and-Swap惯用法 174
24.4.6编写集合的接口 175
24.4.7教学方法 175
24.5mfcstl∷CArray_adaptor_base的接口 176
24.6mfcstl∷CArray_cadaptor 177
24.6.1模板声明和继承 178
24.6.2应用CRTP 178
24.6.3CArray_cadaptor的构造 179
24.6.4operator[]() 180
24.7mfcstl∷CArray_iadaptor 181
24.8CArray_adaptor_base的构造 182
24.9内存分配器 182
24.10元素访问方法 182
24.11元素迭代 183
24.11.1begin()和end() 183
24.11.2rbegin()和rend() 183
24.12和容器大小相关的方法 184
24.13容器容量相关的方法 187
24.14比较相关的方法 187
24.15修改容器结构的方法 190
24.15.1push_back() 190
24.15.2assign() 191
24.15.3popback()和clear() 192
24.15.4erase() 192
24.15.5insert() 193
24.16赋值和swap() 194
24.17总结 196
24.18在CD上 197
第25章 环境变量的map 198
25.l介绍 198
25.2动机 198
25.3getenv()、putenv()、setenv()/unsetenv()和environ 198
25.4platformstl∷enviroment_variable_traits 199
25.5规划接口 201
25.6通过名字查找 201
25.6.1选择1:返回固定/瞬时引用,指向一个缓存对象,具有最新值 202
25.6.2选择2:返回固定引用,指向一个缓存对象,具有快照值 203
25.6.3选择3:返回固定引用,指向一个缓存对象,具有最新值 204
25.6.4选择4:返回按值临时引用,具有最新值 205
25.6.5通过名字查找:尾声 206
25.7通过名字插入、更新和删除值 206
25.8迭代 206
25.8.1第1版:连续迭代器 207
25.8.2第2版:双向迭代器 207
25.8.3第3版:快照 209
25.8.4第4版:引用计数的快照 211
25.9最终的迭代实现 212
25.9.1可变的快照 213
25.9.2创建快照 214
25.9.3constiterator嵌套类 215
25.9.4insert()方法 216
25.9.5erase()方法 217
25.9.6operator[]()和lookup() 218
25.9.7snapshot嵌套类 219
25.10异质的引用类别 220
25.11size()和下标索引 220
25.12总结 221
25.13在CD上 221
第26章 在Z平面上来回穿梭 222
26.1序言 222
26.2介绍 222
26.3第1版:前向迭代 224
26.3.1zorderiterator,第1版 224
26.3.2window_peer_sequence,第1版 225
26.4第2版:双向迭代 226
26.5处理外部更改 227
26.6winstl∷child_window_sequence 229
26.7双向迭代器的蓝调音乐 230
26.7.1end()标记的陷阱 230
26.7.2致命的双重解引用 231
26.7.3当双向迭代器不是前向迭代器,而是可逆可复制迭代器 232
26.8winstl∷zorderiterator:自身的反转 233
26.8.1zorder_iterator特征类 234
26.8.2zorder_iteratortmpl<> 235
26.8.3反向的语义 238
26.9同级窗口序列的定稿 238
26.10总结 239
26.11Z平面:尾声 240
第27章 字符串分词 241
27.1介绍 241
27.2strtok() 241
27.3SynesisSTL∷StringTokeniser 243
27.4字符串分词的用例 244
27.5字符串分词的其他选择 245
27.5.1strtok_r() 245
27.5.2IOStreams 245
27.5.3stlsoft∷find_next_token() 245
27.5.4boost∷tokenizer 245
27.6stlsoft∷string_tokeniser 246
27.6.1stlsoft∷string_tokeniser∷const_iterator 248
27.6.2确定迭代器类别和元素引用类别 250
27.6.3stlsoft∷stringtokeniser_type-traits 250
27.6.4stlsoft∷string_tokeniser_comparator 251
27.7测试代码 253
27.7.1以单个字符作为分隔符 253
27.7.2字符串作为分隔符 254
27.7.3保留空白字段 254
27.7.4复制还是引用:考虑使用“字符串视图”(StringView) 254
27.7.5字符集作为分隔符 256
27.8愚蠢的策略类 256
27.8.1经由继承重构模板参数 257
27.8.2类型生成器模板 258
27.8.3关于Henney假说 258
27.9性能 258
27.10总结 261
第28章 适配COM枚举器 262
28.1介绍 262
28.2动机 262
28.2.1冗长版 262
28.2.2短小版 263
28.3COM枚举器 264
28.3.1IEnumXXXX∷Next() 264
28.3.2IEnumXXXX∷Skip() 264
28.3.3IEnumXXXX∷Reset() 264
28.3.4IEnumXXXX∷Clone() 264
28.3.5枚举器的各种值类型 264
28.4分解冗长版 265
28.5comstl∷enumerator_sequence 266
28.5.1enumerator_sequence的公共接口 266
28.5.2成员类型及成员常量 267
28.5.3值策略(ValuePolicies) 267
28.5.4成员变量 270
28.5.5构造函数 270
28.5.6迭代方法 271
28.5.7迭代器方法的const限定是错误的 272
28.5.8破坏了值语义 272
28.6comstl∷enumerator_sequence∷iterator 273
28.6.1构造 274
28.6.2迭代方法 275
28.6.3equal() 275
28.7comstl∷enumerator_sequence∷iterator∷enumeration_context 276
28.7.1为什么需要枚举上下文 276
28.7.2类定义 277
28.7.3构造 277
28.7.4迭代器的支持方法 281
28.7.5不变量 282
28.8迭代器复制策略 283
28.8.1comstl∷input_cloning_policy 283
28.8.2comstl∷forward_cloning_policy 284
28.8.3comstl∷cloneable_cloning_policy 285
28.9选择默认的复制策略:应用最小意外原则 286
28.10总结 290
28.10.1为什么不默认使用前向迭代器 290
28.10.2为什么不默认使用输入迭代器 290
28.10.3为什么不把Q固定为1 290
28.10.4为什么不使用标准容器 290
28.11后文提要 290
第29章 插曲:运用成员类型推断,纠正设计上的小疏忽 291
第30章 适配COM集合 292
30.1介绍 292
30.2动机 292
30.2.1冗长版 292
30.2.2简洁版 294
30.3comstl∷collection_sequence 295
30.3.1公有接口 295
30.3.2成员类型和常量 296
30.3.3构造 296
30.3.4迭代:干净地利用一个肮脏的把戏 296
30.3.5size() 298
30.4枚举器获取策略 299
30.5总结 301
第31章 聚集分散的I/O 302
31.1介绍 302
31.2分散/聚集I/O 302
31.3分散/聚集I/OAPI 303
31.3.1以COM流实现线性化 303
31.3.2Platformstl∷scatterslicesequence-预告 305
31.4适配ACE_Message_Queue 307
31.4.1acestl∷message_queue_sequence,版本1 308
31.4.2acestl∷message_queue_sequence∷iterator 308
31.5吃蛋糕时间 312
31.5.1再快些 312
31.5.2acestl∷message_queue_sequence,版本2 312
31.5.3特化标准库 314
31.5.4性能 316
31.6总结 317
第32章 根据参数返回不同类型 318
32.1介绍 318
32.2向Ruby借颗宝石 318
32.3C++中的双语义下标 319
32.4通过字符串访问垫片扩大兼容性 320
32.5整数的美中不足 321
32.6选择返回类型和重载 322
32.7总结 322
第33章 外部迭代器失效 324
33.1元素接口一致性 324
33.2Windows的ListBox和ComboBox控件 325
33.2.1提取元素的竞争条件 326
33.2.2WinSTL中的listbox_sequence和combobox_sequence类 327
33.3枚举注册表键和值 331
33.3.1那问题在哪 332
33.3.2WinSTL注册表库 334
33.3.3处理外部迭代器失效问题 334
33.3.4winstl∷basic_reg_key_sequence 336
33.4总结 345
33.5在CD上 345
第三部分 迭代器 348
第34章 增强版ostream_iterator 348
34.1介绍 348
34.2std∷ostreamiterator 349
34.3stlsoft∷ostreamiterator 350
34.3.1垫片的应用 352
34.3.2安全语义 352
34.3.3stlsoft∷ostream_iterator与std∷ostream-iterator的兼容性 353
34.3.4违反了设计原则吗 354
34.4定义流插入运算符 354
34.5小结 355
第35章 插曲:借助解引用代理模式,消除笨拙的输出迭代器语法 356
第36章 变换迭代器 359
36.1介绍 359
36.2动机 360
36.2.1使用std∷transform()的版本 360
36.2.2使用变换迭代器的版本 361
36.3定义迭代器适配器 362
36.3.1创建函数 362
36.3.2值类型 363
36.4stlsoft∷transformiterator 363
36.4.1第一个版本 363
36.4.2构造 365
36.4.3自增、自减运算符和指针算术方法 365
36.4.4比较运算符和算术运算符 365
36.4.5问题在于 366
36.4.6第二个版本 367
36.4.7stlsoft∷transform_iterator 369
36.5复合变换 370
36.6违反了DRYSPOT原则 371
36.6.1使用类型别名和非临时函数对象 371
36.6.2使用异质迭代器和算法 372
36.6.3接受现实,但小心谨慎 374
36.7没准Sequence能帮上点忙 374
36.8小结 375
36.9CD上的内容 375
第37章 插曲:命名时谨慎为好 376
第38章 成员选取迭代器 378
38.1介绍 378
38.2动机 378
38.3stlsoft∷member_selector_iterator 380
38.4创建函数的悲哀 382
38.4.1以非变动性方式访问非常量数组 382
38.4.2以非变动性方式访问常量数组 382
38.4.3以变动性方式访问非常量数组 383
38.4.4通过迭代器类,以非变动性方式访问非常量集合 383
38.4.5通过迭代器类,以非变动性方式访问常量集合 383
38.4.6通过迭代器类,以变动性方式访问集合 385
38.4.7选取常量成员 385
38.5总结 386
38.6在CD上 386
第39章 连接C风格字符串 387
39.1动机 387
39.2不灵活的版本 387
39.3stlsoft∷cstring_concatenator_iterator 389
39.4创建函数 391
39.5总结 391
39.6CD上的内容 392
第40章 字符串对象的连接操作 393
40.1简介 393
40.2stlsoft∷string_concatenatoriterator 393
40.3异质字符串类型的良好协作 395
40.4但是 396
40.4.1关于可赋值性 396
40.4.2悬空引用 396
40.4.3解决方案 396
40.5小结 397
第41章 适配迭代器特征类 398
41.1Introduction 398
41.2stlsoft∷adapted_iterator_traits 398
41.2.1iterator-category 400
41.2.2value-type 400
41.2.3differencetype 400
41.2.4pointer 401
41.2.5reference 401
41.2.6const_pointer和const_reference 402
41.2.7effective-reference和effective_const_reference 402
41.2.8effective_pointer和effective_const_pointer 403
41.2.9使用这个特征类 403
41.3小结 404
41.4CD上的内容 404
第42章 过滤迭代 405
42.1介绍 405
42.2无效版 405
42.3用成员迭代器定义区间 406
42.4那么 406
42.5stlsoft∷filteriterator 407
42.5.1前向迭代器语义 407
42.5.2双向迭代器语义 409
42.5.3随机访问迭代器语义 410
42.6限制迭代器的类别 410
42.7总结 411
42.8在CD上 411
第43章 组合多个迭代器适配 412
43.1介绍 412
43.2转换筛选后的迭代器 412
43.3筛选转换后的迭代器 413
43.4两边下注 414
43.5总结 414
结语 415
参考书目 416