C++基础

C++11 模板元编程 - 前言

2016-09-14  本文已影响1958人  MagicBowen

熟悉C++的程序员都知道,C++是一门多范式编程语言,支持面向过程、面向对象、泛型编程以及函数式编程范式。然而提到C++模板元编程,在很多人心里这却是C++里的黑魔法:它很难学习,一旦进入这个领域曾经那些熟悉的东西(if,for...)都不再灵验;它很强大,但现实中却鲜见有人用它来解决实际问题,除过偶尔在一些编码练习中被某些C++狂热粉当做奇淫巧技拿出来秀秀肌肉。

其实模板元编程是C++所支持的一种非常强大的计算能力,它是使用C++开发高质量库和框架所离不开的一项武器。

掌握C++模板元编程,至少可以在以下场合帮助到你:

如果你是一个C++的库或框架的开发者,了解和掌握一些模板元编程的知识,可以让你的作品更易于扩展、拥有更易用的接口,甚至更高的运行时效率。而即使你只使用C++设计和开发应用程序,了解模板元编程也会帮助你更好的去使用STL库的各种特性,帮助你的局部设计做的更加漂亮。

实际上C++模板元编程技术已经渗透在我们日常使用的各种库和框架中,例如我们最常使用的STL库以及各种xUnit测试框架和mock框架。可以说,模板元编程是中级C++程序员迈向高级的必经之路!

然而现实是,C++模板元编程的学习之旅却并不平坦。

一方面,由于C++模板元编程的本质是函数式编程,熟练掌握并使用函数式编程的程序员比较小众,绝大多数程序员初次进入这个领域时面对模式匹配、递归和不可变性时都会手足无措。另一方面,由于C++的模板元编程能力是被意外发现的,不像别的函数式编程语言经过良好的设计,所以C++的这种函数式计算能力天生存在着各种缺陷,直到C++11标准才开始逐渐完善起来。在之前很多重要特性都靠很绕的方式去迂回实现,增加了学习的难度。

另外,市面上介绍模板元编程的书和资料也乏善可陈,以下的书相对还不错,但对于模板元编程的介绍仍旧存在一些问题:

基于以上原因,我基于C++11标准实现了一个模板元编程的基础库:TLP (https://github.com/MagicBowen/tlp),然后再通过本手册来为大家全面介绍C++模板元编程的基本知识和使用技巧。

TLP库包含以下内容:

除此之外,TLP库中还包含了如下示例代码,用来演示如何在现实场景中应用好模板元编程和TLP库:

上面提到的TypeList以及使用代码生成来创建visitor设计模式的原创者是《Modern C++ Design》的作者Andrei Alexandrescu。在TLP中我用C++11对TypeList及其算法进行了改写,并进行了高阶函数的扩展。得益于C++11标准对模板元编程的更好支持,新的实现比起原来的更加清晰和简洁。

示例代码中利用模板元编程创建有限状态机DSL的设计最初来自于《C++模板元编程》一书,为了让其更好被理解,我对例子以及代码进行了较大的改编。

除了上面的例子,本手册中还介绍了我自己开发的针对C++模块和子系统FT(Functional Test)级别的测试框架dates,展示了它如何使用模板元编程来进行类型萃取、类型选择以及类型校验,最终使得框架变得更易用、更高效以及更安全。这些技巧可以帮助到大家更好地使用模板元编程去解决现实问题。

最后,TLP库自身的测试通过一个原创的C++模板元编程测试框架。该框架专门针对C++编译期计算进行测试,它的用法和常见的xUnit测试框架类似,但有趣的是使用该框架描述的所有测试用例的执行发生在C++编译期。本文会专门介绍该框架的一些实现细节。


C++模板元编程当年被提出来的时候,函数式编程还没有像今天这样被更多的人所了解和接受,当时的C++标准和编译器对模板和编译期计算的支持也存在着很多缺陷。然而到了今天,很多事情发生了变化!本文的读者最好能够有一些函数式编程的基础,了解C++模板的基本用法,熟悉一些C++11标准的内容。当然文中所有用的到模板技术、C++11标准和涉及到的函数式编程概念也都会专门介绍和说明。

如果你从来没有接触过C++模板元编程,那么最好从一开始就把它当做一门全新的语言去学习,从头掌握C++中这种不一样的计算模型和语法。这种新的语言和我们熟识的运行期C++在语法和计算模型上都有较大的差异,但它的优势在于能和运行期C++紧密无缝地结合在一起,无论是在提高程序可扩展性还是提高程序运行效率上,都能创造出非常不可思议的效果来。希望通过本手册,可以让更多的人掌握C++模板元编程这一设计利器,在适合的场合下以更有效、更酷的方式去解决问题。

文中出现的所有代码片段,如果在注释中给出了TLP库中对应的文件路径,则都能在TLP库中找到源码。除此之外的其它代码则是为了文章需要所构造的临时代码。另外,为了减少干扰,本文中所示TLP库中的代码均没有加命名空间,阅读文章和TLP库源码时请注意区分。


模板的基础知识

返回 C++11模板元编程 - 目录

上一篇 下一篇

猜你喜欢

热点阅读