前言:提起模板,你可能会想起一些答题模板或者作文模板,只要套着写就可以,c++98引入了模板这个概念,它可以减少一些重复代码的书写,可以使用一段程序完成多个不同数据类型的处理。
模板分为函数模板和类模板,我们先来学习函数模板。
函数模板
我们现来看一下这段C语言代码。
它可以完成整形的交换,但是如果需要交换double类型呢,就需要在重新写一个交换函数,如果每个类型都要重新写一个函数,这样有点浪费时间了,c++引入的模板就可以很好的解决这个问题。
#include <stdio.h>
void swap(int *a,int *b)
{
int temp=*a;
*a=*b;
*b=temp;
}
int main()
{
int x=10,y=20;
swap(&x,&y);
printf("%d %d",x,y);
}
我们先来看看模板的语法
template<typename T1,typename T2.....>
void swap(T1 x,T2 y){}
template和typename是模板的关键字,T1是类型名,在调用函数时,编译器会帮我们自动匹配参数类型。我们来使用一下这个函数。
#include <iostream>
using namespace std;
template<typename T1,typename T2>
void swap(T1& x,T1 &y)
{
T1&tmp=x;
x=y;
y=tmp;
}
int main()
{
int x=10,y=19;
swap(x,y);
cout<<x<<" "<<y<<endl;
double z=1.2,c=2.1;
swap(z,c);
cout<<z<<" "<<c<<endl;
return 0;
}
我们可以看到swap对int和double的数据都可以进行交换,这样可以减少一些重复的代码
如果只定义了一个模板参数,那么是不可以交换两个不同的参数的,下面这个调用就是错误的,编译器会根据传入的参数进行匹配,但是传入两个类型不同的参数,编译器就不能确定使用哪个参数进行匹配,造成了歧义。
int x = 10;
double c= 1.3;
swap(x, c);
如果要传入两个不同的参数交换,可以使用下面的方法
//1.强制类型转换
swap(x,(int)c);
//或者
swap((double)x,c);
//2.定义两个模板参数
template<typename T1,typename T2>
void swap(T1 x,T2,y){}
用函数模板生成对应的函数叫做模板的实例化。
还有一种可以传入不同参数的方法,它叫做显示实例化,下面是一个例子。
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int main(void)
{
int a = 10;
double b = 20.0;
// 显式实例化
Add<int>(a, b);
return 0;
}
模板函数可以和同名的非模板函数同时存在。下面这段程序不会报错。
编译器会根据匹配程度优先调用非模板函数,如果已经存在与调用参数匹配的函数,编译器也会偷懒,不会自己生成模板函数。
template<typename T>
T Add(T& a, T& b)
{
cout << "模板函数调用" << endl;
return a + b;
}
int Add(int& a, int& b)
{
cout << "非模板函数调用" << endl;
return a + b;
}
int main(void)
{
int a = 10;
int b = 20;
// 显式实例化
Add(a, b);
return 0;
}
调用结果
类模板
除了函数模板外,还有一种模板叫做类模板,它的语法格式和函数模板差不多,不同的是typename需要换成class,下面是语法格式
template<class T1,class T2.....>
class 类模板名
{}
注意:不可以struct替换class
类模板的用法和函数模板差不多,下面是类模板的实例化,需要在类名后加上尖括号,在里面书写要进行操作的数据类型。
template<typename T>
class A
{
public:
T a;
T b;
A(T _a,T _b):a(_a),b(_b){}
};
int main()
{
A<int>(1, 2);
A<double>(2.2, 3.1);
}
今天的文章就到这里了,如果觉得还不错,请点赞关注支持一下,有写的不对的地方还请批评指正。