参数化程序设计——通用的代码就必须不受数据类型的限制,可以把数据类型改为一个设计参数。这种类型的程序设计称为
参数化(parameterize) 程序设计。
这种设计由
模板(template)完成。包括
函数模板(function template)和
类模板(class template)。本节主要讲解函数模板及其应用,类模板请点击这里:C++类模板与线性表
什么是函数模板
看个例子:
// min for ints
int min( int a, int b ) { return ( a < b ) ? a : b; }
// min for longs
long min( long a, long b ){return ( a < b )?a:b; }
// min for chars
char min( char a, char b ){return(a < b )?a : b; }
//etc...
By using templates, you can reduce this duplication to a single function template:
template <typename T> T min( T a, T b )
{ return ( a < b ) ? a : b; }
上例构造了一个求两个数中最小数的函数模板
template <typename T> T min( T a, T b ) ;
用法如下:
#include <iostream.h>
template <typename T> T min( T a, T b )
{
return ( a < b ) ? a : b;
}
void main()
{
int a,a1,a2;
long b,b1,b2;
char c,c1,c2;
cin>>a1>>a2>>b1>>b2>>c1>>c2;
a=min(a1,a2);
b=min(b1,b2);
c=min(c1,c2);
cout<<a<<'/t'<<b<<'/t'<<c<<'/n';
}
函数模板的定义
作用:函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,简化重载函数的设计。函数模板定义如下:
template<模板参数表>返回类型 函数名(形式参数表)
{……;}//函数体
例如:
template <typename T> T min(T a, T b)
{ return ( a < b ) ? a : b; }
说明:
- <模板参数表>的尖括号中不能为空,参数可以有多个,用逗号分开。
- 模板参数主要是模板类型参数。模板类型参数代表某种类型,由关键字 class 或 typename后加一个标识符构成(建议用typename+标识符),这些参数代表一些潜在的内置或用户定义的类型。模板参数名由程序员决定,即可以是任何名字。
【例6.1】用函数模板求数组元素中最大值。(查看源码)
函数模板注意
- 与函数一样,函数模板可以先声明后定义。声明和定义时,模板参数表中所用标识符可以不同,因为模板参数也是按位置来标识的,具体标识符名字只在各自的声明域或函数域内有效。
- 函数模板根据一组实际类型或(和)值构造出独立的函数的过程通常是隐式发生的,称为模板实参推演(template argument deduction)。
- 模板实参推演时,为了判断模板类型参数的实际类型,编译器需检查函数调用中提供的实参类型。ia 的类型为int 数组,id的类型为double 数组。所以,第一次调用时,Gloap被int取代。第二次调用,Groap 被double取代。
- 通过模板实参推演得到的独立函数称为模板函数。如例6.12运行时将产生两个模板函数。
- 也可以显式指定(explicitly specify)模板类型参数的实际类型,见下;这样可读性更好。
int ia[5]={10,7,14,3,25};
double da[6]={10.2,7.1,14.5,3.2,25.6,16.8};
void main()
{
int i=max <int>(ia,5);
cout <<"整数最大值为:"<<i<<endl;
double d=max <double>(da,6);
cout <<“实数最大值为:”<<d<<endl;
}
请注意,这里使用max <int>(ia,5) 和max <double>(da,6),数组名是作为指向数组首元素的指针进行传递,数组长度是由size参数进行传递的。
【例6.2】矩阵运算:矩阵转置与矩阵相乘函数模板。(查看源码)下标作为参数传递。解决例5.5的通用性问题。 - 与函数声明不同,函数模板的声明必须含变量名。因为编译过程不一样,函数模板必须先转换为模板函数。
template <typename T1,typename T2> void inverse(T1 *mat1,T2 *mat2,int a,int b);
template <typename T1,typename T2> void multi(T1 *mat1, T2 *mat2,T2 *result,int a,int b,int c);
template <typename T>void output(T*mat,char*s,int a,int b);
类模板请点击这里:C++类模板与线性表