格式:
// 声明
template // or class T
void Swap(T &a, T &b);
// 定义
template // or class T
void Swap(T &a, T &b)
{
T temp; // temp a variable of type T
temp = a;
a = b;
b = temp;
}
第一行指出要建立一个模板,并将类型命名为T,关键字 template 和 typename 是必须的;
typename 也可以换成关键字 class 来创建模板:
// 声明
template // or class T
void Swap(T &a, T &b);
// 定义
template // or class T
void Swap(T &a, T &b)
{
T temp; // temp a variable of type T
temp = a;
a = b;
b = temp;
}
调用:
int i = 10;
int j = 20;
Swap(i,j);
double x = 24.5;
double y = 81.7;
Swap(x,y);
第一个 Swap 函数接收了两个 int 参数,因此编译器生成 int 版本,也就是用 int 替换所有的 T ,生成下面的定义:
void Swap(int &a, int &b)
{
int temp; // temp a variable of type int
temp = a;
a = b;
b = temp;
}
第二个 Swap 函数接收了两个 double 参数,因此编译器生成 double 版本,也就是用 double 替换所有的 T ,生成下面的定义:
void Swap(double &a, double &b)
{
double temp; // temp a variable of type double
temp = a;
a = b;
b = temp;
}
当然,模板也可以用在函数重载中:
template // original template
void Swap(T &a, T &b);
template // new template
void Swap(T *a, T *b, int n);
调用时会根据输入参数情况,调用相应函数。
具体化:
对于给定的函数名,有非模板、普通模板、显式具体化模板、重载版本;
优先级为:非模板 > 显式具体化模板 > 普通模板
而显示具体化作用是生成指定类型的模板:
struct job
{
...
}
//普通模板
template // or class T
void Swap(T &a, T &b);
//具体化模板
template <> void Swap(job &j1, job &j2);
这时就生成一个类型为 job 的模板,当参数为 job 时,将优先调用:
double u,v;
Swap(u,v);
job a,b;
Swap(a,b);
上述程序第一次将调用普通模板,第二次会调用 job 类型模板;
具体化的意义在于,可以以某个类型定义单独的函数,如下所示:
template
void Swap(T &a, T &b) // general version
{
T temp;
temp = a;
a = b;
b = temp;
}
// swaps just the salary and floor fields of a job structure
template <> void Swap(job &j1, job &j2) // specialization
{
double t1;
int t2;
t1 = j1.salary;
j1.salary = j2.salary;
j2.salary = t1;
t2 = j1.floor;
j1.floor = j2.floor;
j2.floor = t2;
}
此时,job 的具体化模板可以单独修改某个成员变量;
对于普通模板,因为事先不知道是什么类型,所以不方便修改,比如int型就没有成员变量这一说;
实例化:
格式:
//普通模板
template
void Swap(T &a, T &b);
//具体化模板
template <> void Swap(job &j1, job &j2);
//实例化模板
template void Swap(char &j1, char &j2);
与具体化区别在于:
1、template后面少了一个 <> ;
2、调用时使用普通模板生成 char 类型的模板,所以不用单独定义;而具体化是要单独定义的;
3、直接在调用前声明,后面即可使用,不用像具体化那样声明、定义都要有,使用如下:
int main(void)
{
template void Swap(char &j1, char &j2);
char a,b;
Swpa(g,h);
}