前言
PREFACE
C++语言至今拥有40多年的历史,目前最新的C++标准已经发展到了C++20,它给我们带来了相当重要的四大特性:概念约束、ranges(范围)标准库、协程以及模块。
• 概念约束是一个编译期谓词,它根据程序员定义的接口规范对类型、常量等进行编译时检查,以便在泛型编程中为使用者提供更好的可读性与错误信息。
• ranges标准库对现有的标准库进行了补充,它以函数式编程范式进行编程,将计算任务分解为一系列灵活的原子操作,使得代码的正确性更容易推理。
• 协程是一种可挂起、可恢复的通用函数,它的切换开销是纳秒级的,相对其他方案而言占用的资源极低,并且可以非侵入式地为已有库扩展协程接口,它常常用于并发编程、生成器、流处理、异常处理等。
• 模块特性解决了传统的头文件编译模型的痛点:依赖顺序导致头文件难以组合、重复解析、符号覆盖等问题,从语言层面为程序员提供了模块化的手段。
本书针对以上新特性准备了丰富的代码样例,相信读者通过这些代码很容易掌握这些特性。作为一本讲解C++高级编程的书,本书还探讨了很多元编程话题,这是作为库开发必不可少的技能,它们也将随着C++的演进而不断演进,大大提升了库开发者的编程体验,尤其是近年来C++的标准提案经历了从模板元编程向constexpr元编程的转换过程。
纵观C++的演进历程可以发现,每一次演进提供的特性大多数和编译时相关,因为它的特点是零成本抽象,允许程序员表达抽象的概念而无须忍受不必要的运行时开销。而一些运行时特性相当少,在面向对象的虚函数特性之后再无运行时特性,或者它们通常以库的形式提供,例如从C++17起标准库引入的variant类型,它通过元编程技术生成虚函数表。
C++对语言特性与库特性区分得非常清楚,它希望程序员能够在不引入语言机制的情况下实现一些功能,例如其他编程语言常常将元组tuple作为内建类型,而在C++中它们以库的方式提供,程序员能够利用现有的语言特性实现这些组件。
如何合理、高效地运用这些知识,它们背后通常蕴含着什么指导思想?那就是组合式思想,将问题分而治之,从而能够应对许多难题。C++语言提供了足够多的抽象机制,允许程序员提出各种假设,并基于这些假设进行灵活组合。
本书话题不局限于C++20,对现代C++中很多重要的特性也会深入探讨,例如右值引用。一些编程原则,面向对象设计模式也会探讨。最后一章将带领读者实现两个库:配置文件反序列库与协程库。它们大量使用C++20提供的特性,并使用元编程的方式构建,以对全书知识进行一个总结。
本书要求读者需要有C++的基础知识,最好能够掌握一些现代C++的知识,考虑到市面上的书籍以及网络上这方面的资料比较丰富,笔者在提及这些知识时会引用相关链接供读者查阅。对于想要系统性学习C++20并进阶C++技能的读者,一定不要错过本书。
本书创作历时一年多,笔者在工作与业余时间不断磨炼C++技能,这期间很多人为我提供了帮助与支持,没有你们本书就不可能问世。
感谢我所在的工作团队为我提供了良好的工作环境,让我能够随心所欲地探索软件上的新技术。其间,袁英杰大师加入了我们团队参与开发,给我带来了很大的启发。
我从他身上学到了很多编程思想,这些思想并不是空谈,而是真真切切能够影响到整个编码过程,并且指导了我的软件开发工作。在与袁英杰大师共事的几个月里,我感受到了大师代码里处处充满组合式思想,泛型、抽象运用得非常优雅,能够充分应对软件开发中的各种变化。
偶然在公司的一次关于软件重构的演讲中,我认识了吴咏炜老师,从那时起,我们便时常交流C++相关话题,在交流过程中我也学习到了很多。吴咏炜老师牺牲个人时间为本书做技术校对,他非常细心,帮我避免了很多技术上以及排版上的错误,并且对一些章节提出了调整建议。
由于C++20刚标准化不久,业界的很多优秀资料都是英文的。在我创作过程中阅读这些资料难免会遇到困难,职愈博(Norman Zhi)给我在一些语法上的理解提供了帮助。他是一位优秀的硬件工程师,有时候我们会讨论很多与Linux、性能、C语言相关的话题,这也为本书提供了一些灵感。
机械工业出版社的李晓波编辑也为本书能够顺利出版提供了帮助。还要感谢读者选择了这本书,期待你能够从中获得启发。最后,感谢我的妻子,正是你的鼓励、付出与陪伴,才让我能够专心完成本书的创作。
罗能