|
@@ -223,8 +223,53 @@ template <typename T> void foo()
|
|
|
}
|
|
|
```
|
|
|
|
|
|
-####1.2.2 模板函数的使用
|
|
|
+无论是函数模板还是类模板,在实际代码中看起来都是“千变万化”的。这些“变化”,主要是因为类型被当做了参数,导致代码中可以变化的部分更多了。
|
|
|
+
|
|
|
+归根结底,模板无外乎两点:
|
|
|
+
|
|
|
+ 1. 函数或者类里面,有一些类型我们希望它能变化一下,我们用标识符来代替它,这就是“模板参数”;
|
|
|
+
|
|
|
+ 2. 在需要这些类型的地方,写上相对应的标识符(“模板参数”)。
|
|
|
+
|
|
|
+当然,这里的“可变”实际上在代码编译好后就固定下来了,可以称之为编译期的可变性。
|
|
|
+
|
|
|
+这里多啰嗦一点,主要也是想告诉大家,模板其实是个很简单的东西。
|
|
|
+
|
|
|
+下面这个例子,或许可以帮助大家解决以下两个问题:
|
|
|
+
|
|
|
+ 1. 什么样的需求会使用模板来解决?
|
|
|
+
|
|
|
+ 2. 怎样把脑海中的“泛型”变成真正“泛型”的代码?
|
|
|
+
|
|
|
+```
|
|
|
+举个例子:generic typed function ‘add’
|
|
|
+```
|
|
|
+
|
|
|
+在我遇到的朋友中,即便如此对他解释了模板,即便他了解了模板,也仍然会对模板产生畏难情绪。毕竟从形式上来说,模板类和模板函数都要较非模板的版本更加复杂,阅读代码所需要理解的内容也有所增多。
|
|
|
|
|
|
+如何才能克服这一问题,最终视模板如平坦代码呢?
|
|
|
+
|
|
|
+答案只有一个:无他,唯手熟尔。
|
|
|
+
|
|
|
+在学习模板的时候,要反复做以下的思考和练习:
|
|
|
+
|
|
|
+ 1. 提出问题:我的需求能不能用模板来解决?
|
|
|
+
|
|
|
+ 2. 怎么解决?
|
|
|
+
|
|
|
+ 3. 把解决方案用代码写出来。
|
|
|
+
|
|
|
+ 4. 如果失败了,找到原因。是知识有盲点(例如不知道怎么将 `T&` 转化成 `T`),还是不可行(比如试图利用浮点常量特化模板类,但实际上这样做是不可行的)?
|
|
|
+
|
|
|
+通过重复以上的练习,应该可以对模板的语法和含义都有所掌握。如果提出问题本身有困难,或许下面这个经典案例可以作为你思考的开始:
|
|
|
+
|
|
|
+ 1. 写一个泛型的数据结构:例如,线性表,数组,链表,二叉树;
|
|
|
+
|
|
|
+ 2. 写一个可以在不同数据结构、不同的元素类型上工作的泛型函数,例如求和;
|
|
|
+
|
|
|
+当然和“设计模式”一样,模板在实际应用中,也会有一些固定的需求和解决方案。比较常见的场景包括:泛型(最基本的用法)、通过类型获得相应的信息(型别萃取)、编译期间的计算、类型间的推导和变换(从一个类型变换成另外一个类型,比如boost::function)。这些本文在以后的章节中会陆续介绍。
|
|
|
+
|
|
|
+####1.2.2 模板函数的使用
|
|
|
|
|
|
###1.3 整型也可是Template参数
|
|
|
|