模板的发明是为了避免过多无用的重复劳动或重复代码,在某一个函数或类中,要处理许多不同的数据类型,但处理方式和逻辑大同小异,此时,使用模板,将数据类型暂时抽象表示,等到实际使用时在明确数据类型,即可节约大量工作量。
template
T add(T a,T b){
return a+b;
}
int main() {
int a=3;
int b=5;
float c=2.3;
float d=1.4;
cout<
模板函数格式如最上方四行所示,用template关键词说明这是个模板函数,用typename规定抽象化的数据类型是什么,typename可以替换为class,在类模板中同样如此。T是自定义的名字,你可以换一个。
在main函数中,即使不事先声明,编译器也会自动确定具体的数据类型是什么,并作出相应操作。运行后,输出数值为8和3.7。
此外,数据类型可以是结构体或类,但这样一来,可能要涉及到运算符重载的内容。
类模板的定义与模板函数类似,也是在常规的类定义语句前加一句template,后面接尖括号,括号里是typename关键字和抽象化的类型名。例如:
template
class map{
public:
map(){this->K=0, this->V=0;}
map(key k, value v){
this->K=k,this->V=v;
}
value get_value(){
return V;
}
key get_key(){
return K;
}
private:
key K;
value V;
};
int main() {
mapm1(3,5);
cout<m2(2.6,8);
cout<
运行后,输出数值为3和2.6,因为可以从模板类的构造函数中得知,第一个参数会给key赋值,第二个参数给value赋值,而get_key函数可以获得key值。
可见,类模板使用时,一定要在声明时,在类名和实例名之间加上尖括号,在里面指明数据类型。为了方便,类模板还可以自定义默认数据类型,例如:
template
class map{
public:
map(){this->K=0, this->V=0;}
map(key k, value v){
this->K=k,this->V=v;
}
private:
key K;
value V;
};
int main() {
mapm1(2.6,1.2);
mapm2(2.6,1.2);
return 0;
}
可以看到,在第一行,value后面多了一个=float,则在m1中,因为只指定了一个数据类型,编译器便默认第二个数据类型是float。
你可能会问,如果把=float放在key后面,编译器怎么知道只有一个数据类型参数时,应该把传递进来的数据类型给谁呢?实际上,这种情况不允许出现,带有默认类型的,一定要放在没有默认类型的后面。在声明一个实例时,尖括号里的数据类型数量要大于等于没有声明默认类型的typename数。
可以看出,模板函数和类模板最大的不同有两点: