2023年8月2日,周三上午
目录
- 模板的分类
- 语法
- 模板实例化
- 示例程序
- 深入理解模板参数
模板的分类
模板分为函数模板和类模板。
语法
template<typename 模板参数1,...>
返回值类型 函数名(参数列表){
}
template是一个关键字,用于声明模板
<>用于存放模板参数
typename也是一个关键字,用于标识模板参数,可用class关键字替代
注:模板参数不能为空;模板参数可以有多个;可以不使用模板参数
/*-------------------------
模板参数不能为空
-------------------------*/
template<>
int swap(int a,int b){
return a+b;
}
/*-------------------------
typename可以用class来替代
-------------------------*/
template<typename T>
void swap(T &x,T &y){
int tmp=x;
x=y;
y=tmp;
}
template<class T>
void swap(T &x,T &y){
int tmp=x;
x=y;
y=tmp;
}
/*-------------------------
模板参数可以有多个
-------------------------*/
template<class T1,class T2>
void printType(T1 x,T2 y){
const std::type_info& type1 = typeid(x);
const std::type_info& type2 = typeid(y);
std::cout << type1.name() << std::endl;
std::cout << type2.name() << std::endl;
}
/*-------------------------
可以不使用模板参数
-------------------------*/
template<typename T>
int swap(int a,int b){
return a+b;
}
模板实例化
程序运行时,模板的参数由传入的实参的数据类型决定,编译器会根据传入的实参的数据类型生成相应的一段可运行的代码,这个过程叫做模板实例化。
函数模板生成的实例称为模板函数,类模板生成的实例称为模板类
示例程序
#include<iostream>
template<typename T>
void swap(T &x,T &y){
T tmp=x;
x=y;
y=tmp;
}
int main(){
char c1='A',c2='G';
int i1=10,i2=99;
std::cout<<"before swapping"<<std::endl;
std::cout<<"c1="<<c1<<" "<<"c2="<<c2<<std::endl;
std::cout<<"i1="<<i1<<" "<<"i2="<<i2<<std::endl;
swap(c1,c2);
swap(i1,i2);
std::cout<<"after swapping"<<std::endl;
std::cout<<"c1="<<c1<<" "<<"c2="<<c2<<std::endl;
std::cout<<"i1="<<i1<<" "<<"i2="<<i2<<std::endl;
return 0;
}
深入理解模板参数
为什么声明模板时,要在template后面加上<class T1,class T2,...>?
加上<class T1,class T2,...>是为了能够在接下来的函数定义中使用模板参数。
如果你不写<class T1,class T2,...>的话,你怎么在接下来的函数定义中使用这些模板参数?
编译器可没智能到能无中生有。