第1章 Hello模板
概述
C++(www.cppentry.com)可称为强类型语言,凡值必有类型,凡变量声明时必声明其类型,且变量类型“一生”不变。除少数预设类型外,不同类型值之间不能自动转换,除非有用户自定义的相关构造函数和类型转换函数。如此则编译时已知各变量所占内存大小,编译器可精确规划变量值在内存与寄存器间之调度,提高运行效率。而其弊端是代码无法独立于类型之外。对于某些算法,针对不同数据其操作过程完全一致,只因所操作数据类型不同,在C++(www.cppentry.com)中需实现为不同的函数,难免重复。
1.1 为什么需要模板
以从一列值中找出最大值为例,其算法可概述为“设置一个变量max_value,从列中选择某一元素值作为max_value初值;然后将max_value与列中其余元素一一比较,更新max_value为其中较大值,待全部元素比较完毕,则max_value的值即列中最大值”。以上叙述都不涉及具体元素类型,可见算法描述可脱于类型之外。
如果以某种动态类型语言,比如Python,来实现此算法则非常简洁。在Python中,一个从序列中寻找最大值并返回的函数其代码可写成以下形式:
- def max_element(l):
- max_value = l[0]
- for elem in l[1:]:
- if elem > max_value: max_value = elem
- return max_value
-
- print max_element([2, 0, 1, 1, 0, 8, 1, 8])
- print max_element(['2011', 'August', '11', 'Thursday'])
Python中变量类型随所赋值而变,因此函数max_element的参数l既可接纳整数列表,又可接纳字符串列表。又因为在Python中字符串默认按字典顺序比较大小,所以无论是整数列表还是字符串列表都适用上述代码。而函数中变量max_value既可接受“整数”值,也可接受“字符串”值。正因变量类型可变,同一函数可用于在各种列表中寻最大值。
但使用C++(www.cppentry.com)实现一个通用的max_element函数就不那么简单。由于C++(www.cppentry.com)中变量的类型不可变,不能像Python那样用同一函数、同一变量处理不同类型的列表。如果没有模板,则必须根据所操作列表类型确定函数参数以及内部各变量的类型。假如列表为一个整数数组,则函数代码可写成例1.1的形式。
例1.1
- int max_element(int const *l, unsigned sz)
- {
- int max_value = l[0];
- for (unsigned i = 1; i < sz; ++i)
- if (l[i] > max_value) max_value = l[i];
- return max_value;
- }
假如列表为一个字符数组,则函数代码可写成例1.2的形式。
例1.2
- char max_element(char const *l, unsigned sz)
- {
- char max_value = l[0];
- for (unsigned i = 1; i < sz; ++i)
- if (l[i] > max_value) max_value = l[i];
- return max_value;
- }
除函数返回值、第一个参数l以及局部变量max_value的类型以外,两个函数其余部分完全一样。只因列表数据类型不同,不得不将同一算法反复实现。如此机械繁复的工作,本应由机器代为完成。而利用C++(www.cppentry.com)的模板机制,便可根据给定类型自动生成所需函数。所以,我们与模板的“第一次亲密接触”,就从一个函数模板开始。