From c3a9257a8a5ba05eb33b2bcf5b9e9773ea34247d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Feb 2014 14:00:11 -0800 Subject: [PATCH] =?UTF-8?q?=E6=92=B0=E5=86=992.1=E8=8A=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ReadMe.md | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/ReadMe.md b/ReadMe.md index 5ec3d48..ea62313 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -514,6 +514,71 @@ template class E {}; // ERROR: 别闹!早说过只能是整数类 ## 2. 模板元编程基础 ###2.1 编程,元编程,模板元编程 + +技术的学习是一个登山的过程。第一章是最为平坦的山脚道路。而从这一章开始,则是正式的爬坡。无论是我写作还是你阅读,都需要付出比第一章更多的代价。那么问题就是,付出更多的精力学习模板是否值得? + +这个问题很功利,但是一阵见血。因为技术的根本目的在于解决需求。那C++的模板能做什么? + +一个高(树)大(新)上(蜂)的回答是,C++里面的模板,犹如C中的宏、C#和Java中的自省(restropection)和反射(reflection)一样,是一个改变语言内涵,拓展语言外延的存在。 + +程序最根本的目的是什么?复现真实世界或人所构想的规律,减少重复工作的成本,或通过提升规模完成人所不能及之事。但是世间之事万千,有限的程序如何重现复杂的世界呢? + +答案是“抽象”。论及具体手段,无外乎“求同”与“存异”:概括一般规律,处理特殊情况。这也是软件工程所追求的目标。一般规律概括的越好,我们所付出的劳动也就越少。 + +同样的,作为脑力劳动的产品,程序本身也是有规律性的。《Modern C++ Design》中的前言就抛出了一连串有代表性的问题: + +``` +如何撰写更高级的C++程式? +如何应付即使在很干净的设计中仍然像雪崩一样的不相干细节? +如何构建可复用组件,使得每次在不同程式中应用组件时无需大动干戈? +``` + +我们以数据结构举例。在程序里,你需要一些堆栈。这个堆栈的元素可能是整数、浮点或者别的什么类型。一份整型堆栈的代码可能是: + +``` C++ +class StackInt +{ +public: + void push(Int v); + Int pop(); + Int Find(Int x) + { + for(Int i = 1; i <= size; ) + { + if(data[i] == x) { return i; } + } + } + // ... 其他代码 ... +}; +``` + +如果你要支持浮点了,那么你只能将代码再次拷贝出来,并作如下修改: + +``` C++ +class StackFloat +{ +public: + void push(Float v); + Float pop(); + Int Find(Float x) + { + for(Int i = 1; i <= size; ) + { + if(data[i] == x) { return i; } + } + } + // ... 其他代码 ... +}; +``` + +当然也许你觉得这样做能充分体会代码行数增长的成就感。但是有一天,你突然发现:呀,`Find` 函数实现有问题了。怎么办?这个时候也许你只有两份这样的代码,那好说,一一去修正就好了。如果你有十个呢?二十个?五十个? + +时间一长,你就厌倦了这样的生活。你觉得每个堆栈都差不多,但是又有点不一样。为了这一点点不一样,你付出了太多的时间。吃饭的时间,泡妞的时间,睡觉的时间,看岛国小电影顺便练习小臂力量的时间。 + +于是便诞生了新的技术,来消解我们的烦恼。 + +这个技术的名字,并不叫“模板”,而是叫“元编程”。 + ###2.2 模板世界的If-Then-Else:类模板的特化与偏特化 ###2.3 函数模板的重载、参数匹配、特化与部分特化 ###2.4 技巧单元:模板与继承