
Boost是一个功能强大、构造精巧、跨平台、开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉。 Boost由C++标准委员会部分成员所设立的Boost社区开发并维护,使用了许多现代C++编程技术,内容涵盖字符串处理、正则表达式、容器与数据结构、并发编程、函数式编程、泛型编程、设计模式实现等许多领域,极大地丰富了C++的功能和表现力,能够使C++软件开发更加简捷、优雅、灵活和高效。 本书基于2014年11月发布的Boost 1.57版,介绍了其中的所有129个库,并且结合C++11/14标准详细、深入地讲解了其中数十个库,同时实现了若干颇具实用价值的工具类和函数,可帮助读者迅速地理解、掌握Boost的用法并应用于实际的开发工作。
推荐序 最近一年我电话面试了数十位C++应聘者,惯用的暖场问题是“工作中使用过STL的哪些组件?用过Boost的哪些组件?”得到的答案大多集中在vector、map和shared_ptr。如果对方是在校学生,我一般会问问vector或map的内部实现、各种操作的复杂度,以及迭代器失效的可能场景。如果是有经验的程序员,我还会追问shared_ptr的线程安全性、循环引用的后果及如何避免、weak_ptr的作用等。如果这些都回答得不错,进一步还可以问问如何实现线程安全的引用计数,如何定制删除动作等。这些问题让我能迅速地判别对方的C++水平。 我之所以在面试时问到Boost,是因为其中的许多组件确实可以用于编写可维护的产品代码。Boost包含近百个程序库,其中不乏具有工程实用价值的佳品。每个人口味与技术背景不一样,对Boost的取舍也不一样。就我的个人经验而言,首先可以使用绝对无害的库,例如noncopyable、scoped_ptr、static_assert等,这些库的学习和使用都比较简单,容易入手。其次,有些功能自己实现起来并不困难,正好Boost里提供了现成的代码,那就不妨一用,比如date_time和circular_buffer等。然后,在新项目中,对于消息传递和资源管理可以考虑采用更加现代的方式,例如用function/bind在某些情况下代替虚函数作为库的回调接口、借助shared_ptr实现线程安全的对象回调等。这二者会影响整个程序的设计思路与风格,需要通盘考虑,如果正确使用智能指针,在现代C++程序里一般不需要出现delete语句。最后,对某些性能不佳的库保持警惕,比如lexical_cast。总之,在项目组成员人人都能理解并运用的基础上,适当引入现成的Boost组件,以减少重复劳动,提高生产力。 Boost是一个宝库,其中既有可以直接拿来用的代码,也有值得借鉴的设计思路。试举一例:正则表达式库regex对线程安全的处理。 早期的RegEx类不是线程安全的,它把“正则表达式”和“匹配动作”放到了一个类里边。由于有可变数据,RegEx的对象不能跨线程使用。如今的RegEx明确地区分了不可变(immutable)与可变(mutable)的数据,前者可以安全地跨线程共享,后者则不行。比如正则表达式本身(basic_regex)与一次匹配的结果(match_results)是不可变的;而匹配动作本身(match_regex)涉及状态更新,是可变的,于是用可重入的函数将其封装起来,不让这些数据泄露给别的线程。正是由于做了这样合理的区分,RegEx在正常使用时就不必加锁。 Donald Knuth 在“Coders at Work”一书里表达了这样一个观点:如果程序员的工作就是摆弄参数去调用现成的库,而不知道这些库是如何实现的,那么这份职业就没啥乐趣可言。换句话说,固然我们强调工作中不要重新发明轮子,但是作为一个合格的程序员,应该具备自制轮子的能力。非不能也,是不为也。 C/C++语言的一大特点是其标准库可以用语言自身实现。C标准库的strlen、strcpy、strcmp系列函数是教学与练习的好题材,C++标准库的complex、string、vector则是类、资源管理、模板编程的绝佳示范。在深入了解STL的实现之后,运用STL自然手到擒来,并能自动避免一些错误和低效的用法。 对于Boost也是如此,为了消除使用时的疑虑,为了用得更顺手,有时我们需要适当了解其内部实现,甚至编写简化版用作对比验证。但是由于Boost代码用到了日常应用程序开发中不常见的高级语法和技巧,并且为了跨多个平台和编译器而大量使用了预处理宏,阅读 Boost源码并不轻松惬意,需要下一番功夫。另一方面,如果沉迷于这些有趣的底层细节而忘了原本要解决什么问题,恐怕就舍本逐末了。 Boost中的很多库是按泛型编程的范式来设计的,对于熟悉面向对象编程的人而言,或许面临一个思路的转变。比如,你得熟悉泛型编程的那套术语,如concept、model、refinement,才容易读懂Boost.Threads文档中关于各种锁的描述。我想,对于熟悉STL设计理念的人而言,这不是什么大问题。 在某些领域,Boost不是唯一的选择,也不一定是最好的选择。比如,要生成公式化的源代码,我会首选用脚本语言写一小段代码生成程序,而不用Boost.Preprocessor;要在C++程序中嵌入领域特定语言,我会首选用Lua或其他语言解释器,而不用Boost.Proto;要用C++程序解析上下文无关文法,我会首选用ANTLR来定义词法与语法规则并生成解析器(parser),而不用Boost.Spirit。总之,使用Boost时心态要平和,别较劲去改造C++语言。把它有助于提高生产力的那部分功能充分发挥出来,让项目从中受益才是关键。 要学习Boost,除了阅读其官方网站的文档、示例与源码之外,最好能有一本比较全面的中文书在手边随时翻阅。对于不谙英文的开发者,这更是可幸之至。您手上这本《Boost 程序库完全开发指南》是很好的使用指南与参考手册。作者由浅入深地介绍了Boost的大部分常用内容,能让读者迅速了解Boost,并从中找到自己需要的部分。拿到这本书稿之后,我有粗有细地阅读了一遍,总体来看,作者水平很高,也相当务实,对C++和Boost的理解与运用很到位,我从这本书学到了不少新知识。为此,我乐于向希望学习Boost程序库的开发者推荐这本靠谱的书。 须知“功不唐捐”,作为一名现代C++程序员,在Boost上投入的精力定能获得回报。 陈硕 《代码大全》译者之一 中国香港 第3版前言 对第2版的改动 本版的目标是向C++11/14标准靠拢。 鉴于这些变化,第2版在保持原书风格的同时做了适当调整,删去了一些浅显的部分,并依据最新的C++11和Boost程序库全面更新,较第1版略增加深度,但仍然还是以入门为主,不过多介绍库的实现细节。由于C++11标准有很多新的语言特性和库,包含了部分Boost库原有的功能,故作者弱化了一些与C++11语言特性重复的库,对于库组件则着重讲解符合C++11标准的功能。 第2版使用了4个开发环境,处理不同系统之间的兼容问题令人头疼,特别是要“照顾”不支持C++11标准的编译器而不能使用新特性,编写代码有种“捆住了手脚”的感觉。故本次只使用Linux操作系统,编译器也使用最新的GCC4.8,可以及时跟进C++的最新发展。 本书第3版的重大变化列举如下。 第0章 : 重新组织了结构,增加GitHub源码资源; 第1章 : 新增构建工具b2的介绍,删除了STLPort和Windows相关内容; 第3章 : 新增make_unique()/intrusive_ptr等很多新内容, 删除了auto_ptr相关的阐述; 第4章 : 新增ignore_unused、explicit_operator_bool等内容, 更新optional和assign库,删除了typeof; 第5章 : 新增string_ref库,更新了lexical_cast; 第6章 : 新增lightweight test,调整了assert; 第8章 : 新增clamp、hex等算法; 第9章 : 新增math.constants和ratio库,调整了rational; 第10章 : 新增chrono库,删除了io_state_savers; 第11章 : 增加对C++11里lambda表达式的论述,删除了result_of; 第12章 : 新增atomic库,完全重写了thread和asio的介绍, 增加了大量新内容,如UNIX信号、协程等; 第13章 : 更新至Boost1.57版,删除了原13章boost.python; 第14章 : 新增了一个对象池模式; 附录 : 完善对C++11/14/17标准的介绍,删除了STL简介。 致谢 前两版的致谢已经够多了,但我还是要感谢可敬可爱的读者,希望本书依然是您工作中不可或缺的伙伴。 罗剑锋 2015年1月5日于北京 第2版前言 本书第1版面世至今忽忽然不觉已经两年有余,其间多蒙读者厚爱,褒奖有加,不胜感激,在此聊写些文字,以志心性。 闲谈碎语C++ 这两年里对于C++社区来说最重大的事件莫过于是C++11标准的发布了:历经十余年的磨砺,崭新的C++终于扬刀出鞘,诸多新语言特性和库的加入令C++旧貌换新颜,从此程序员手里的这把宝刀更是增添了无穷的威力,上天入地屠龙伏虎,不在话下。 最近开源界的一桩新闻也不得不提一下:著名的C/C++编译器GCC于2012年8月完成了从C实现到C++实现的转换。虽然这件事比不上C++11发布,但足可以从一个侧面证明C++的实力已经得到了开源界的高度认可,今后没有什么是C++做不出来的了。 作为C++标准的后备,随着C++11的正式发布,Boost程序库现在进入了一个新的历史时期:一方面依据新标准不断完善自身,另一方面则秉承传统继续开拓C++11未涉及的领域。这两方面可以从Boost历次巨细靡遗的更新记录中看出来——不断修正既有库中不符合标准的地方,同时再谨慎地引入新的组件,“小步快跑”地奔向“康庄大道”。 由于Boost程序库正逐渐向C++11标准靠拢,曾经的“准标准库”美誉已经不太合适了,它更像是一个比C++标准库更加“兼容”、更加“标准”的“超级标准库”——使用Boost可以完全消除C++11和C++98之间的差异,稍微有点夸张地说:学习Boost就相当于学习现代C++,使用现代C++必然避不开Boost。 国内外的许多公司都已经把Boost作为自己源码资产的一部分,在这些高质量的软件组件之上开发产品,更激进的如Facebook则是走在了潮流的前面,同时使用最新的C++11和Boost来开发软件(如开源的folly)。面对新技术,我们应该克服心中的怯懦和懒惰,积极学习,力争“站在C++98的最高峰沐浴C++11的阳光”。 对第1版的改动 本书第1版撰写于2010年年初,彼时C++新标准尚未确定,国内了解、使用Boost的人也不多,故书的内容偏重于入门和介绍。而现在的情况则已经大有不同:C++11标准相当于是一个全新的语言,获得了诸多编译器生产商的积极响应,移动互联网的兴起也使得国内的程序员群体开始越来越多地关心起C++和Boost,整体C++水平有所提升。 鉴于这些变化,第2版在保持原书风格的同时做了适当调整,删去了一些浅显的部分,并依据最新的C++11和Boost程序库全面更新,较第1版略增加深度,但仍然是以入门为主,不过多介绍库的实现细节。由于C++11标准有很多新的语言特性和库,包含了部分Boost库原有的功能,故作者弱化了一些与C++11语言特性重复的库,对于库组件则着重讲解符合C++11标准的功能。 本书第2版几乎每页都较前一版有修改,各章的重大变化列举如下。 第1章 : 重新组织了结构,分别介绍UNIX和Windows开发环境; 第3章 : 增加对unique_ptr的介绍,补充完善对weak_ptr的论述; 第4章 : typeof库推荐改用C++11的auto,删除4.11.3节; 第6章 : 增加对C++11 static_assert关键字的介绍; 第7章 : array、unordered、tuple库更新为C++11标准; 第8章 : foreach推荐改用C++11的for,minmax库更新为C++11标准; 第9章 : random库更新为C++11标准; 第10章 : 新增cpu_timer库,system更新为C++11标准,filesystem更 新为V3; 第11章 : result_of、ref、bind、function等库更新为C++11标准; 第12章 : thread库更新为符合C++11标准的V3(变动非常大); 第14章 : 更新至Boost1.51版; 附录 : 补充了对C++11标准的简介,同时删除了用处不大的网络资源和 ref_array源代码。 第1版的版式个人感觉比较满意,但代码行多的时候还是不容易阅读,所以本次对部分重要的代码片段加粗醒目,用于提醒读者注意要点。 作者最早的开发环境是Windows,近年来工作重心逐渐转移,Mac OS X和Linux成了主力工作环境(个人非常欣赏Apple公司),因此第2版中淡化了Windows操作系统的色彩,不再细述VC相关的配置,示范代码也基本改为UNIX风格,请读者明鉴。 致谢 同第1版一样,我首先要感谢Bjarne Stroustrup博士、C++标准委员会和C++/Boost社区,感谢他们长久以来的坚持和努力,为我们带来了C++11标准和越来越接近完美的Boost程序库。 然后是我的家人:感谢我的父母、弟弟和妻子,你们永远是我生命中最重要的人;感谢即将满4岁的女儿,这本书是和你一同成长起来的,希望你将来能够读懂它。 最后感谢读者选择本书,希望和您再次一起分享学习C++和Boost的快乐。 罗剑锋 2012年10月12日于北京WFC 第1版前言 屈指算来,接触C++语言至今已经有十余个年头了。回首往事,不禁感慨良多。 缘起 1996年我上大学最开始学的是Pascal,不得不说,Pascal严谨的程序风格确实很适合作为一门教学语言,然而用于实际开发就不那么合适了(直到出现Delphi)。由于当时学校并未开设C语言课程,因此在Pascal课程结束后我就买书自学C/C++语言,并在次年报名计算机软件专业技术资格和水平考试,靠着一点点编程和考试的“天分”获得了高级程序员资质(当年很热衷考级考证,后来就“淡定”多了)。虽然有了资格证,但我仍然算是个C++的初学者,对于C++的认识还处于C的面向过程和简单的基于对象层次上。 新千年伊始我考入了北京理工大学就读研究生,因为跟导师做项目开始接触STL与C++标准库,大概是2005年从1.33版结识了Boost,这才真正领略了C++的精髓。那段时期Java和C#正在国内大行其道,C++则势单力薄,有关STL和C++标准的技术书籍寥寥无几,而讲解Boost的书更是为零,故对Boost的学习基本只能靠自己的摸索与实践。好在Boost自带的文档相当丰富(尽管看全英文的资料十分辛苦),而且源码也写得比较清晰规范,在熟悉了STL的基础上学习Boost倒也并不算太难。 但Boost的一个最大的特点就是“庞大”,功能组件众多,要想把它全部装进脑子里融会贯通基本上是不可能的,使用时需要经常查阅英文文档,相当麻烦。因此,在学习的过程中,我逐渐产生了编写学习笔记的想法。一开始只是一个简单的纯文本文件,记录了一些使用经验的片断,随着积累不断增加,纯文本形式已经不能够满足知识整理的需求了,于是我又把这些文字迁移到了Word文档里,把使用经验分类编目,进行较系统的归纳梳理。慢慢地,这份学习笔记居然有了上万字的规模,成为了一份很好的Boost备忘参考,在日常的开发工作中给了我很大的帮助——就像《设计模式》一书中所说的那样,捕获了很多使用Boost解决问题的实践经验,避免了重复发现。不过,这份资料一直仅限于我个人使用,属于“自娱自乐”的作品,从未示人。 时间一晃到了2010年1月份的某天夜里,不知道是什么原因我忽然失眠了,躺在床上翻来覆去怎么也睡不着。突然,一个念头闯入了脑海:把Boost开发经验整理出版吧,让更多人能够分享这些知识,正所谓“独乐乐,与众乐乐,孰乐?”这个大胆的想法的出现让我那天的失眠又延长了几个小时——关于书的各种构想在头脑中“肆虐横行”。 随后的几天里我就把这个想法付诸行动了,虽然以前也写过并发表很多文章,也在网上印刷了几本个人文集,但出版正式的书还是第一次。在把学习笔记进一步整理完善,编写出较完整的结构和一个样章后,我就开始联系出版社了。当初并没有多大的信心,毕竟我这个作者名不见经传,也没有什么资历、背景和名气(而且还是个“网盲”,从未跟随潮流开个人博客)。很幸运,发出的第一个E-mail就是电子工业出版社,而且编辑也在第一时间回复了我,这才给了我持续写作完成全书的动力。 写作过程中我也进一步加深了对Boost的认识,澄清了许多原来未曾注意到的细节。原本只打算写20万字左右、300多页,但写到中途才发现Boost库的博大精深远非当初的理解,也意识到了自己当初学习的肤浅。历经了近半年近乎不眠不休的努力,最终呈现给读者的是这本厚达500多页的图书,文字量是最初学习笔记的数十倍,内容也翔实丰满了很多——达成这个结果,我个人可以说是问心无愧了。 C++与Boost C++较Java和C#等语言的一个最大不同在于它并非是由某个公司或个人把持的,它的真正发展动力来自于广大程序员。Boost就是这样的一个典范,它成功地填补了从C++98到C++0X这“失落的十年”间的空白,在竞争对手Java和C#不断更新版本新增特性的时候以库的形式极大地增强了C++的能力,使C++不至于因为标准规范的滞后而落后于时代,而且Boost还深层次地挖掘了C++的潜力,开创了泛型编程、模板元编程、函数式编程等崭新的境界。 就个人来说,我比较喜欢的Boost版本有两个,分别是1.35和1.39。1.35版增加了asio、bimap、circular_buffer等许多重要组件,而1.39版则增加了signals2库,这两个版本都在我的工作用机上停留了相当长的时间。落笔之时,Boost已经更新到了1.43版,成长为一个相当完善、全面、强大的C++程序库。可以毫不夸张地说,现在的C++程序员,如果不熟悉Boost,那么至少丧失了一半使用C++的好处,同时会多耗费数倍的开发精力和时间。 随着C++0X标准的即将来临,Boost程序库的发展也出现了加速的趋势,由原来间隔数月不定期更新版本,改为定期(每3个月左右)发布新版本,而且每个新版本都会包含大量极有价值的更新内容。因此,希望读者在阅读本书时及时访问Boost的官网(http://www.boost.org),以便获取最新的版本。 感谢读者选择本书,再说一句真心的“套话”(笑):限于作者水平有限,书中错漏在所难免,敬请读者原谅、指正。 致谢 首先我要感谢整个C++群体,特别是:C++语言的发明者Bjarne Stroustrup博士——他给我们带来了美妙的C++;然后是Alexander Stepanov和C++标准委员会——他们把STL引入了C++,开创了C++的现代编程风格;以及Beman G. Dawes、Boost程序库的所有作者和Boost社区——他们为我们奉献了如此高水准的程序库。 其次我要感谢电子工业出版社博文视点公司,他们给了我这个把自己的开发经验出版成书的机会,在把潦草的个人学习笔记变成正式图书的过程中他们付出了艰辛的努力。还要感谢陈硕先生,他审阅了本书的部分手稿,提出了很多有价值的参考意见,并慨然为本书撰写序言。 接下来我要感谢我的家人:感谢我的父母和弟弟,他们永远是我生命中最重要的人;感谢我的妻子,她自始至终都支持我的写作,并担负了大部分照顾孩子的家务(虽然偶有怨言);还要对已满一岁半的女儿说声抱歉,为了写作本书,我已经牺牲了很多陪她玩耍的时间。 我还要感谢黄美华、冯薇、戚天龙、罗玉震、颜静、陈刚、张秋香、缪泽波等同事,长期的共事令我们建立了深厚的友谊。对后两位同事致以特别的感谢,他们对完成本书提供了大力的支持和帮助。 最后,感谢多年以来的好友岳大海、时吉斌、王峰,感谢我的中学老师邓英、杜爱芹、练鑫云、陈静,感谢我的研究生导师贾云得,以及所有在我成长过程中曾经给予我关心和帮助的朋友们! 罗剑锋 2010年6月7日于北京王府井
目录 第0章 导读 1 0.1 关于本书 1 0.2 读者对象 1 0.3 术语与风格 2 0.4 C++标准 3 0.5 本书的结构 4 0.6 如何阅读本书 5 0.7 本书的源码 5 第1章 Boost程序库总论 7 1.1 关于Boost 7 1.1.1 获取方式 8 1.1.2 目录结构 8 1.1.3 使用方式 9 1.2 开发环境 9 1.2.1 操作系统和编译器 10 1.2.2 快捷安装Boost 10 1.2.3 完全安装Boost 10 1.2.4 定制安装Boost 11 1.2.5 验证开发环境 11 1.3 构建工具 12 1.3.1 安装b2 12 1.3.2 构建脚本 12 1.3.3 构建语言 13 1.3.4 构建命令 14 1.4 总结 14 第2章 时间与日期 15 2.1 timer库概述 15 2.2 timer 16 2.2.1 用法 16 2.2.2 类摘要 17 2.2.3 使用建议 18 2.3 progress_timer 18 2.3.1 用法 18 2.3.2 类摘要 19 2.4 progress_display 20 2.4.1 类摘要 20 2.4.2 用法 21 2.4.3 注意事项 22 2.5 date_time库概述 23 2.5.1 编译与使用 24 2.5.2 基本概念 24 2.6 处理日期 25 2.6.1 日期 25 2.6.2 创建日期对象 26 2.6.3 访问日期 27 2.6.4 日期的输出 28 2.6.5 转换tm结构 29 2.6.6 日期长度 29 2.6.7 日期运算 31 2.6.8 日期区间 32 2.6.9 日期区间运算 33 2.6.10 日期迭代器 35 2.6.11 其他功能 36 2.6.12 综合运用 36 2.7 处理时间 39 2.7.1 时间长度 39 2.7.2 操作时间长度 40 2.7.3 时间长度的精确度 42 2.7.4 时间点 43 2.7.5 创建时间点对象 44 2.7.6 操作时间点对象 45 2.7.7 转换tm/time_t结构 46 2.7.8 时间区间 46 2.7.9 时间迭代器 47 2.7.10 综合运用 47 2.8 date_time库的高级议题 50 2.8.1 编译配置宏 50 2.8.2 自定义字面值 51 2.8.3 格式化时间 51 2.8.4 本地时间 52 2.8.5 序列化 54 2.9 总结 54 第3章 内存管理 57 3.1 smart_ptr库概述 57 3.1.1 RAII机制 57 3.1.2 智能指针 58 3.2 scoped_ptr 59 3.2.1 类摘要 59 3.2.2 操作函数 60 3.2.3 用法 61 3.2.4 对比unique_ptr 63 3.2.5 make_unique 64 3.3 scoped_array 65 3.3.1 类摘要 65 3.3.2 用法 66 3.3.3 对比unique_ptr 66 3.3.4 使用建议 67 3.4 shared_ptr 68 3.4.1 类摘要 68 3.4.2 操作函数 69 3.4.3 用法 70 3.4.4 工厂函数 72 3.4.5 应用于标准容器 73 3.4.6 应用于桥接模式 74 3.4.7 应用于工厂模式 75 3.4.8 定制删除器 77 3.4.9 高级议题 78 3.5 shared_array 82 3.5.1 类摘要 82 3.5.2 用法 82 3.6 weak_ptr 83 3.6.1 类摘要 83 3.6.2 用法 84 3.6.3 enable_shared_from_this 85 3.6.4 enable_shared_from_raw 86 3.6.5 打破循环引用 88 3.7 intrusive_ptr 89 3.7.1 类摘要 89 3.7.2 用法 90 3.7.3 引用计数器 91 3.8 pool库概述 92 3.9 pool 93 3.9.1 类摘要 93 3.9.2 操作函数 94 3.9.3 用法 95 3.10 object_pool 95 3.10.1 类摘要 96 3.10.2 操作函数 96 3.10.3 用法 97 3.10.4 使用更多的构造参数 97 3.11 singleton_pool 99 3.11.1 类摘要 99 3.11.2 用法 99 3.12 pool_alloc 100 3.13 总结 101 第4章 实用工具 103 4.1 noncopyable 103 4.1.1 原理 104 4.1.2 用法 104 4.1.3 实现 105 4.2 ignore_unused 106 4.2.1 基本用法 106 4.2.2 模板用法 107 4.3 optional 108 4.3.1 类摘要 108 4.3.2 操作函数 109 4.3.3 用法 111 4.3.4 工厂函数 112 4.4 assign 113 4.4.1 list_inserter 113 4.4.2 使用operator+= 114 4.4.3 使用operator () 115 4.4.4 generic_list 116 4.4.5 初始化容器 117 4.4.6 减少重复输入 119 4.4.7 操作非标准容器 120 4.4.8 其他议题 121 4.5 swap 122 4.5.1 原理 122 4.5.2 交换数组 123 4.5.3 特化std::swap 124 4.5.4 特化ADL可找到的swap 125 4.5.5 使用建议 126 4.6 singleton 126 4.6.1 类摘要 126 4.6.2 用法 127 4.7 tribool 128 4.7.1 类摘要 129 4.7.2 用法 130 4.7.3 为第三态更名 131 4.7.4 输入/输出 131 4.7.5 与optional<bool>的区别 132 4.8 operators 133 4.8.1 基本运算概念 134 4.8.2 算术操作符的用法 135 4.8.3 基类链 137 4.8.4 复合运算概念 138 4.8.5 相等与等价 140 4.8.6 解引用操作符 141 4.8.7 下标操作符 142 4.8.8 bool转型操作符 143 4.8.9 二元操作符 145 4.9 exception 145 4.9.1 标准库中的异常 146 4.9.2 类摘要 146 4.9.3 向异常传递信息 148 4.9.4 错误信息类 149 4.9.5 包装标准异常 151 4.9.6 使用函数抛出异常 152 4.9.7 获得更多的调试信息 152 4.9.8 高级议题 154 4.10 uuid 155 4.10.1 类摘要 156 4.10.2 用法 157 4.10.3 生成器 158 4.10.4 增强的uuid类 160 4.10.5 转换字符串 162 4.10.6 SHA1摘要算法 163 4.11 config 164 4.11.1 BOOST_STRINGIZE 164 4.11.2 BOOST_STATIC_ CONSTANT 165 4.12 utility 165 4.12.1 BOOST_BINARY 165 4.12.2 BOOST_CURRENT_ FUNCTION 167 4.13 总结 168 第5章 字符串与文本处理 171 5.1 lexical_cast 171 5.1.1 函数声明 172 5.1.2 用法 172 5.1.3 错误处理 173 5.1.4 对转换对象的要求 174 5.1.5 应用于自定义类 175 5.1.6 对比C++11标准 176 5.2 format 177 5.2.1 简单的例子 178 5.2.2 输入操作符% 179 5.2.3 类摘要 180 5.2.4 格式化语法 182 5.2.5 format的性能 183 5.2.6 高级用法 183 5.3 string_ref 184 5.3.1 类摘要 185 5.3.2 用法 186 5.4 string_algo 188 5.4.1 简单的例子 188 5.4.2 string_algo概述 189 5.4.3 大小写转换 190 5.4.4 判断式(算法) 191 5.4.5 判断式(函数对象) 193 5.4.6 分类 193 5.4.7 修剪 194 5.4.8 查找 195 5.4.9 替换与删除 197 5.4.10 分割 199 5.4.11 合并 200 5.4.12 查找(分割)迭代器 201 5.5 tokenizer 203 5.5.1 类摘要 203 5.5.2 用法 204 5.5.3 分词函数对象 204 5.5.4 char_separator 205 5.5.5 escaped_list_separator 206 5.5.6 offset_separator 207 5.5.7 tokenizer库的缺陷 208 5.6 xpressive 210 5.6.1 两种使用方式 210 5.6.2 正则表达式语法简介 211 5.6.3 类摘要 212 5.6.4 正则匹配 214 5.6.5 正则查找 217 5.6.6 正则替换 218 5.6.7 正则迭代 219 5.6.8 正则分词 221 5.6.9 对比boost.regex 222 5.6.10 高级议题 223 5.7 总结 225 第6章 正确性与测试 227 6.1 assert 227 6.1.1 基本用法 227 6.1.2 禁用断言 229 6.1.3 扩展用法 229 6.2 static_assert 231 6.2.1 定义 231 6.2.2 用法 231 6.2.3 使用建议 233 6.3 lightweight_test 233 6.3.1 测试断言 233 6.3.2 用法 234 6.3.3 测试元编程 235 6.4 test 235 6.4.1 最小化的测试套件 236 6.4.2 单元测试框架简介 237 6.4.3 测试断言 238 6.4.4 测试用例与测试套件 239 6.4.5 测试实例 240 6.4.6 测试夹具 242 6.4.7 测试日志 244 6.4.8 运行参数 245 6.4.9 函数执行监视器 246 6.4.10 程序执行监视器 249 6.4.11 高级议题 249 6.5 总结 251 第7章 容器与数据结构 253 7.1 array 253 7.1.1 类摘要 254 7.1.2 操作函数 254 7.1.3 用法 255 7.1.4 能力限制 256 7.1.5 初始化 257 7.1.6 零长度的数组 257 7.1.7 对比C++11标准 258 7.2 dynamic_bitset 258 7.2.1 类摘要 259 7.2.2 创建与赋值 260 7.2.3 容器操作 261 7.2.4 位运算与比较运算 262 7.2.5 访问元素 263 7.2.6 类型转换 264 7.2.7 集合操作 265 7.2.8 综合运用 265 7.3 unordered 267 7.3.1 散列集合简介 267 7.3.2 散列集合的用法 269 7.3.3 散列映射简介 271 7.3.4 散列映射的用法 272 7.3.5 高级议题 274 7.4 bimap 276 7.4.1 类摘要 276 7.4.2 基本用法 277 7.4.3 值的集合类型 278 7.4.4 集合类型的用法 279 7.4.5 使用标签类型 281 7.4.6 使用assign库 282 7.4.7 查找与替换 283 7.4.8 投射 285 7.4.9 高级议题 285 7.5 circular_buffer 286 7.5.1 类摘要 287 7.5.2 用法 288 7.5.3 环形缓冲区 288 7.5.4 空间优化型缓冲区 290 7.6 tuple 290 7.6.1 最简单的tuple:pair 291 7.6.2 类摘要 292 7.6.3 创建与赋值 292 7.6.4 访问元素 293 7.6.5 比较操作 295 7.6.6 输入输出 295 7.6.7 联结变量 296 7.6.8 应用于assign库 297 7.6.9 应用于exception库 298 7.6.10 内部结构 298 7.6.11 使用访问者模式 299 7.6.12 高级议题 301 7.7 any 303 7.7.1 类摘要 303 7.7.2 访问元素 304 7.7.3 用法 305 7.7.4 简化的操作函数 306 7.7.5 保存指针 307 7.7.6 输出 308 7.7.7 应用于容器 309 7.8 variant 310 7.8.1 类摘要 310 7.8.2 访问元素 311 7.8.3 用法 312 7.8.4 访问器 313 7.8.5 与any的区别 315 7.8.6 高级议题 316 7.9 multi_array 317 7.9.1 类摘要 318 7.9.2 用法 319 7.9.3 改变形状和大小 321 7.9.4 创建子视图 321 7.9.5 适配普通数组 323 7.9.6 高级议题 324 7.10 property_tree 326 7.10.1 类摘要 327 7.10.2 读取配置信息 328 7.10.3 写入配置信息 330 7.10.4 更多用法 331 7.10.5 XML数据格式 332 7.10.6 其他数据格式 333 7.10.7 高级议题 335 7.11 总结 336 第8章 算法 339 8.1 foreach 339 8.1.1 用法 340 8.1.2 详细解说 341 8.1.3 更优雅的名字 342 8.1.4 支持的序列类型 343 8.1.5 存在的问题 344 8.2 minmax 344 8.2.1 用法 345 8.2.2 存在的问题 345 8.3 minmax_element 346 8.3.1 用法 346 8.3.2 其他函数的用法 347 8.4 algorithm 348 8.4.1 clamp 348 8.4.2 clamp_range 349 8.4.3 hex和unhex 349 8.5 总结 350 第9章 数学与数字 353 9.1 math.constants 353 9.1.1 基本用法 354 9.1.2 高级用法 355 9.2 integer 355 9.2.1 integer_traits 355 9.2.2 标准整数类型 357 9.2.3 整数类型模板类 359 9.3 rational 362 9.3.1 类摘要 362 9.3.2 创建与赋值 363 9.3.3 算术运算与比较运算 364 9.3.4 类型转换 365 9.3.5 输入输出 365 9.3.6 分子与分母 365 9.3.7 与数学函数配合工作 366 9.3.8 rational的精确度 366 9.3.9 最大公约数和最小公倍数 366 9.4 ratio 367 9.4.1 类摘要 367 9.4.2 用法 368 9.4.3 数字单位 369 9.4.4 字符串表示 371 9.4.5 对比C++11标准 372 9.5 crc 372 9.5.1 类摘要 372 9.5.2 预定义的实现类 373 9.5.3 用法 373 9.6 random 375 9.6.1 随机数发生器 375 9.6.2 随机数发生器的拷贝 377 9.6.3 随机数分布器 377 9.6.4 随机数分布器类摘要 378 9.6.5 随机数分布器用法 381 9.6.6 变量发生器 382 9.6.7 产生随机数据块 383 9.6.8 真随机数发生器 384 9.6.9 实现真随机数发生器 385 9.7 总结 387 第10章 操作系统相关 389 10.1 system 389 10.1.1 错误值枚举 390 10.1.2 错误类别 390 10.1.3 错误代码 392 10.1.4 错误异常 394 10.2 chrono 395 10.2.1 时间长度 395 10.2.2 使用时间长度 396 10.2.3 时钟 398 10.2.4 时间点 400 10.2.5 综合运用 402 10.3 cpu_timer 404 10.3.1 时间类型 404 10.3.2 cpu_timer 405 10.3.4 auto_cpu_timer 406 10.3.5 定制输出格式 407 10.4 filesystem 408 10.4.1 类摘要 409 10.4.2 路径表示 411 10.4.3 可移植的文件名 412 10.4.4 路径处理 413 10.4.5 异常处理 415 10.4.6 文件状态 416 10.4.7 文件属性 418 10.4.8 文件操作 419 10.4.9 迭代目录 420 10.4.10 实例1:实现查找 文件功能 423 10.4.11 实例2:实现模糊查找 文件功能 424 10.4.12 实例3:实现拷贝 目录功能 426 10.4.13 文件流操作 427 10.5 program_options 428 10.5.1 概述 429 10.5.3 选项值 431 10.5.4 选项描述器 432 10.5.5 选项描述器的用法 433 10.5.6 分析器 435 10.5.7 存储器 436 10.5.8 使用位置选项值 437 10.5.9 分析环境变量 439 10.5.10 分组选项信息 440 10.5.11 高级用法 442 10.6 总结 445 第11章 函数与回调 447 11.1 ref 447 11.1.1 类摘要 448 11.1.2 基本用法 449 11.1.3 工厂函数 450 11.1.4 操作包装 450 11.1.5 综合应用 451 11.1.6 对比C++11标准 452 11.2 bind 453 11.2.1 工作原理 454 11.2.2 绑定普通函数 455 11.2.3 绑定成员函数 456 11.2.4 绑定成员变量 458 11.2.5 绑定函数对象 458 11.2.6 使用ref库 459 11.2.7 对比C++11标准 460 11.2.8 高级议题 460 11.3 function 463 11.3.1 类摘要 464 11.3.2 function的声明 465 11.3.3 操作函数 465 11.3.4 比较操作 466 11.3.5 用法 466 11.3.6 使用ref库 468 11.3.7 用于回调 469 11.3.8 对比C++11的auto 471 11.3.9 对比std::function 472 11.4 signals2 472 11.4.1 类摘要 473 11.4.2 操作函数 474 11.4.3 插槽的连接与调用 475 11.4.4 信号的返回值 477 11.4.5 合并器 477 11.4.6 管理信号的连接 479 11.4.7 更灵活的管理信号连接 480 11.4.8 自动连接管理 483 11.4.9 应用于观察者模式 485 11.4.10 高级议题 488 11.5 总结 492 第12章 并发编程 495 12.1 atomic 495 12.1.1 类摘要 496 12.1.2 基本用法 498 12.1.3 整数atomic的用法 499 12.1.4 并发顺序一致性 500 12.2 thread 503 12.2.1 mutex 503 12.2.2 lock_guard 506 12.2.3 unique_lock 507 12.2.4 lock适配器 510 12.2.5 lockable概念检查类 512 12.2.6 lock函数 512 12.2.7 thread 513 12.2.8 使用线程 515 12.2.9 中断线程 518 12.2.10 thread_group 521 12.2.11 call_once 522 12.2.12 条件变量 523 12.2.13 shared_mutex 527 12.2.14 future 529 12.2.15 shared_future 533 12.2.16 高级议题 534 12.3 asio 536 12.3.1 概述 537 12.3.2 UNIX信号 543 12.3.3 定时器 549 12.3.4 网络通信概述 554 12.3.5 同步TCP通信 560 12.3.6 异步TCP通信 562 12.3.7 解析网络地址 568 12.3.8 协程 570 12.3.9 其他议题 573 12.4 总结 577 第13章 Boost组件速览 579 13.1 算法 579 13.2 字符串和文本处理 580 13.3 容器与数据结构 580 13.4 迭代器 581 13.5 函数对象与高级编程 582 13.6 泛型编程 583 13.7 模板元编程 585 13.8 预处理元编程 585 13.9 并发编程 586 13.10 数学与数字 587 13.11 TR1实现 588 13.12 输入输出 588 13.13 C++11特性模拟实现 588 13.14 杂项 589 13.15 总结 591 第14章 Boost与设计模式 593 14.1 创建型模式 594 14.2 结构型模式 595 14.3 行为模式 598 14.4 其他模式 601 14.5 总结 603 第15章 结束语 605 15.1 未臻完美的Boost 605 15.2 让Boost工作得更好 606 15.3 工夫在诗外 608 15.4 临别赠言 610 附录A 推荐书目 611 附录B C++标准简述 613 附录C C++关键字浅谈 617