首页 > 代码库 > templates(1.1)

templates(1.1)

为什么使用 Templates?

C++ 要求我们使用各种特定类型(specific types)来声明变量、函数和其它各种实体(entities); 然而,很多用以处理「不同类型之数据」的程序代码看起来都差不多。特别是当你实作算法(像是quicksort),或实作如 linked-list 或 binary tree 之类的数据结构时,除了所处理的类型不同,程序代码实际上是一样的。如果你使用的编程语言并没有针对这个问题支持某种特殊的语言特性,那么你有数种退而次之的选择:

1. 针对每一种类型写一份程序代码。

2. 使用 common base type(通用基础类型,例如 Object 或 void*)来编写代码。

3. 使用特殊的 preprocessors(预处理器。译注:意指编译之前预先处理的宏, macros)。

如果你是从 C、Java 或其它类似语言转到C++ 阵营,可能这三种方法你都用过。但是每一种方法都有其缺点:

1. 如果为每一种类型写一份程序代码,你就是「不断做重复的事情」。你会在每一份程序代码中犯下相同的错误(如果有的话),而且不敢使用更复杂但更好的算法,因为这会带来更多错误。

2. 如果你使用一个 common base class(通用基础类别),就无法获益于「类型检验」。而且某些 classes 可能必须从其它特殊的 base classes 继承而来,这就给程序维护工作带来更多困难。

3. 如果你使用特殊的 preprocessors(预处理器),例如 C/C++ preprocessors,你将失去「格式化源码」(formatted source code)的好处。预处理机制对于作用域(scope)和类型(types)一无所知,只是进行简单的文字替换。

Templates 可以解决你的问题,而又不带上述提到的缺点。所谓 templates,是为「尚未确定之型别」所写的 functions 或 classes。使用 templates 时,你可以显式(明确)或隐式(隐喻)地将型 别当做自变量(argument)来传递。由于 templates 是一种语言特性,类型检查(type checking)和 作用域(scope)的好处不会丧失。

Templates 如今已被大量运用。就拿 C++标准库来说,几乎所有程序代码都以 templates 写成。 标准库提供各式各样的功能:对 objects 和 values 排序的各种算法、管理各种元素的数据 结构(容器类别,container classes)、支持各种字符集的 string(字符串)。Templates 使我们得以将程序的行为参数化、对程序代码优化(最佳化),并将各种信息参数化。这些都会在后续章节中讲述。

函数模板

本章将介绍 function templates。所谓 function templates 是指藉由参数化手段表现一整个族群的 。

Function templates 可为不同类型的数据提供作用行为。一个 function template 可以表示一族(一整群)functions,其表现和一般的 function 并无二致,只是其中某些元素在编写时尚未确定。换言之,那些「尚未确定的元素」被「参数化」了。让我们看一个实例。

2.1.1 定义 Template

下面的 function template 传回两个数值中的较大者:

// basics/max.hpp
template <typename T>
inline T const& max (T const& a, T const& b)
{
  // 如果 a<b 就传回 b,否则传回 a
  return a < b ? b : a;
}

在 function template 被调用时,经由传递具体类型而使 T 得以被具体指定。你可以使用任何类型(包括基本类型和 class 类型等等), 只要它支持T 所要完成的操作。本例中类型 T 必须支持operator< 以比较两值大小。