CppTemplateTutorial/ReadMe.md

7.0 KiB
Raw Blame History

C++ Template 进阶指南

0. 前言

###0.1 C++另类简介:比你用的复杂,但比你想的简单

C++似乎从他为世人所知的那天开始便成为天然的话题性编程语言。在它在周围有着形形色色的赞美与贬低之词。当我在微博上透露欲写此文的意愿时,也收到了很多褒贬不一的评论。作为一门语言,能拥有这么多使用并恨着它、使用并畏惧它的用户,也算是语言丛林里的奇观了。

C++之所以变成一门层次丰富、结构多变、语法繁冗的语言是有着多层次的原因的。Bjarne在《The Design and Evolution of C++》一书中详细的解释了C++为什么会变成如今C++98/03的模样。这本书也是我和陈梓瀚一直对各位已经入门的新手强烈推荐的一本书。通过它你多少可以明白C++的诸多语法要素之所以变成如今的模样,实属迫不得已。

模板作为C++中最有特色的语言特性它堪称玄学的语法和语义理所应当的成为初学者的梦魇。甚至很多工作多年的人也对C++的模板部分保有充分的敬畏。在多数的编码标准中Template俨然和多重继承一样成为了一般程序员非程序库撰写者的禁区。甚至运用模板较多的Boost的也成为了“众矢之的”。

但是实际上C++模板远没有想象的那么复杂。我们只需要换一个视角在C++03的时候模板本身就可以独立成为一门“语言”。它有“值”有“函数”有“表达式”和“语句”。除了语法比较蹩脚外它既没有指针也没有数组更没有C++里面复杂的继承和多态。可以说它要比C语言要简单的多。如果我们把模板当做是一门语言来学习那只需要花费学习OO零头的时间即可掌握。按照这样的思路可以说在各种模板书籍中出现的多数技巧都可以被轻松理解。

简单回顾一下模板的历史。87年的时候泛型Generic Programming变被纳入了C++的考虑范畴并直接导致了后来模板语法的产生。可以说模板语法一开始就是为了在C++中提供泛型机制。92年的时候Alexandar Stepanov开始研究利用模板语法制作程序库后来这一程序库发展成STL并在93年被接纳入标准中。

此时不少人以为STL已经是C++模板的集大成之作C++模板技止于此。但是在95年的《C++ Report》上John Barton和Lee Nackman提出了一个矩阵乘法的模板示例。可以说元编程在那个时候开始被很多人所关注。自此篇文章发表之后很多人大牛都开始对模板产生了浓厚的兴趣。其中对元编程技法贡献最大的当属Alexandrescu的《Modern C++ Design》及模板程序库Loki。这一2001年发表的图书间接地导致了模板元编程库的出现。书中所使用的Typelist等泛型组件和Policy等设计方法令人耳目一新。但是因为全书用的是近乎Geek的手法来构造一切设施因此使得此书阅读起来略有难度。

2002年出版的另一本书《C++ Templates》可以说是在Template方面的集大成制作。它详细阐述了模板的语法、提供了和模板有关的语言细节信息举了很多有代表性例子。但是对于模板新手来说这本书细节如此丰富让他们随随便便就打了退堂鼓缴械投降。

本文的写作初衷,就是通过“编程语言”的视角,介绍一个简单、清晰的“模板语言”。我会尽可能的将模板的诸多要素连串起来,用一些简单的例子帮助读者学习这门“语言”,让读者在编写、阅读模板代码的时候,能像 if(exp) { dosomething(); }一样的信手拈来,让“模板元编程”技术成为读者牢固掌握、可举一反三的有用技能。

###0.2 适宜读者群

因为本文并不是用于C++入门,例子中也多少会牵涉一些其它知识,因此如果读者能够具备以下条件,会读起来更加轻松:

  • 熟悉C++的基本语法;
  • 使用过STL
  • 熟悉一些常用的算法,以及递归等程序设计方法。

此外尽管第一章会介绍一些Template的基本语法但是还是会略显单薄。因此也希望读者能对C++ Template最基本语法形式有所了解和掌握如果会编写基本的模板函数和模板类那就更好了。

诚如上节所述本文并不是《C++ Templates》的简单重复与《Modern C++ Design》交叠更少。从知识结构上我建议大家可以先读本文再阅读《C++ Templates》获取更丰富的语法与实现细节以更进一步《Modern C++ Design》除了元编程之外还有很多的泛型编程示例原则上泛型编程的部分与我所述的内容交叉不大读者在读完1-3章了解模板的基本规则之后便可阅读《MCD》的相应章节元编程部分如Typelist建议在阅读完本文之后再行阅读或许会更易理解。

###0.3 版权

本文是随写随即同步到Github上因此在行文中难免会遗漏引用。本文绝大部分内容应是直接承出我笔但是也不定会有他山之石。所有指涉内容我会尽量以引号框记或在上下文和边角注记中标示如有遗漏烦请不吝指出。

全文所有为我所撰写的部分,作者均保留所有版权。如果有需要转帖或引用,还请注明出处并告知于我。

1. Template的基本语法

###1.1 Template Class的基本语法 ###1.2 Template Function的基本语法 ###1.3 整型也可是Template参数

2. 模板世界的If-Then-Else特化与偏特化

###2.1 实例化/特化类模板:从类模板到可以定义变量的具体类 ###2.2 类模板的匹配规则:特化与部分特化 ###2.3 函数模板的重载、特化与部分特化 ###2.4 技巧单元:模板与继承

3 拿起特化的武器,去写程序吧!

###3.1 利用模板特化规则实现If-Then-Else与Switch-Case ###3.2 特化可以有多个选择:替换失败并不是一个错误,只是一种可能 ###3.3 技巧单元获得类型的属性——类型萃取Type Traits

4 用模板写程序吧!骚年!

###4.1 模板上的递归 ###4.2 将循环变成递归,将分支变成递归,将一切变成递归 ###4.3 实战单元元编程的Fibonacci数列 ###4.4 技巧单元typename与template的另一种用法 ###4.5 实战单元:撰写你自己的元编程“函数”库 ###4.6 实战单元实现元编程上的数据结构——以Vector为例

5 关于模板,你还需要知道的其它常识

###5.1 类中类:灵活的模板定义 ###5.2 Template-Template Class ###5.3 技巧单元:高阶函数——从函数到函数的组合 ###5.4 实战单元STL中的Allocator Rebinder ###5.5 像看堆栈一样的看出错信息 ###5.6 模板的症结:易于实现,难于完美

alexandrescu 关于 min max 的讨论《再谈Min和Max》

6 C++11的新特性

###6.1 变参模板 ###6.2 Lambda与模板程序

7 结语:讨论有益,争端无用