Browse Source

撰写2.1节。

unknown 11 years ago
parent
commit
c3a9257a8a
1 changed files with 65 additions and 0 deletions
  1. 65 0
      ReadMe.md

+ 65 - 0
ReadMe.md

@@ -514,6 +514,71 @@ template <float a> 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 技巧单元:模板与继承