C++中一种编程思想称之为泛型编程,主要利用的是模板。
模板
概念:建立一个通用的模具,提高复用性。
特点:不可直接使用,只是一个框架,模板的通用不是万能的。
一、函数模板
作用:建立一个通用函数,其函数返回值类型和形参类型可以不具体制定,用一个虚拟的类型来代表。
template<class T>
函数声明或定义
template——声明创建模板
class或typename——表示其后面的符号为一种数据类型。
如:交换两个变量进行交换。
#include<iostream>
using namespace std;
template<class T>
void Swap(T &a,T &b){
T temp=a;
a=b;
b=temp;
}
int main(){
int a1=1,b1=3;
double a2=2.2,b2=3.3;
char a3='a',b3='c';
Swap(a1,b1);//自动类型推到 ,显示直接定参数类型Swap<int>(a1,b1);
Swap(a2,b2);
Swap(a3,b3);
cout<<a1<<" "<<b1<<endl;
cout<<a2<<" "<<b2<<endl;
cout<<a3<<" "<<b3<<endl;
return 0;
}
注意事项:
自动类型推导,必须推导出一致的数据类型T,才能使用。
模板必须要确定出数据类型,才能使用。
//错误实例
template<class T>
void fun(){
cout<<"fun 调用"<<endl;
}//T的类型没有被确定
void main(){
int a=10;
double b=20;
Swap(a,b);//因为两个变量不一样,需要一致的T
}
普通函数和函数模板调用规则:
函数模板可以进行重载。
两者名字可以相同,但优先调用普通函数。
可以用空模板参数列表来强制调用函数模板。
如果函数模板可以产生更好的匹配,优先调用函数模板。
#include<iostream>
using namespace std;
//普通函数和函数模板调用规则:
//两者可以进行函数重载,并且优先调用普通函数。
//可以用空模板参数列表来强制调用函数模板。
//如果函数模板可以产生更好的匹配,优先调用函数模板。
void print(int a,int b){
cout<<"调用普通函数"<<endl;
}
template<class T>
void print(T a,T b){
cout<<"调用函数模板"<<endl;
}
template<class T>
void print(T a,T b,T c){
cout<<"调用重载的函数模板"<<endl;
}
void test01(){
int a=20;
int b=10;
int c=100;
// print(a,b);//都是int类型,优先调用普通函数
//通过空模板参数列表来强制调用函数模板
// print<>(a,b); //空模板列表
// print (a,b,c);//可以发生重载
}
void test02(){
char a='a';
char b='b';
print(a,b);
}
int main(){
test01();
test02();
return 0l;
}
注意:既然提供了函数模板,最好不要再提供普通函数,否则容易出现二义性。
函数模板的局限性:
函数模板不是万能的,如数组无法使用,用户自定义的数据类型无法使用。
template <class T>
void t(T a,T b){
a=b;//若是数组则无法使用
}
利用具体化的模板可以解决自定义类型的通用化。
template <>bool compare(person &p1,person &p2){//person是用户自定义的类
if(p1.name==p2.name&&p1.age==p2.age){
return true;
}else{
return false;
}
}
学习模板不是为了写模板,而是在STL能运用系统所提供的模板。