void Swap(int& left, int& right)
{
int tmp = left;
left = right;
right = tmp;
}
上述代码是一个简单的交换函数,但是只能用来交换int,要想交换其他类型的变量,则需要重新写一个,但是代码的重复率极高,只有参数类型不一样,为了提高代码的复用率,C++提出了模板
函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定
类型版本
template<typename T1,typename T2,...,typename Tn>
void Swap(T& left, T& right)
{
T tmp = left;
left = right;
right = tmp;
}
template
函数返回值 函数名(参数列表) {}
与定义普通函数相似,只不过在函数名上加上了template
,然后在函数中将与类型无关的通用代码用T来替换,
注意:
函数模板只是一张蓝图,并不是一个函数,是编译器用使用方式产生特定具体类型函数的模具,是编译器帮我们多做了事情
- 在编译阶段,编译器会通过传入的实参类型进行推导,并生成对应类型的函数
函数模板的实例化分为隐式实例化和显式实例化
#include
using namespace std;
template<class T>
T Add(T left, T right)
{
return left + right;
}
int main()
{
int a1 = 10, a2 = 20;
double c1 = 30.4,c2 = 50.6;
Add(a1, a2);
Add(c1, c2);
//Add(a1, c1); //报错
return 0;
}
编译器在推导T的类型时,a1为int的类型,而c1为double的类型,但是模板中只有一个T,无法推导出T的类型是什么类型,所以会报错
注意:在模板中,编译器一般不会进行类型转换操作,因为一旦转化出问题,编译器就需要背黑锅
解决方法:
Add(a1, (int)c1);
Add(a1, c1);
#include
using namespace std;
template<class T>
T Add(T left, T right)
{
return left + right;
}
int main()
{
int a = 10;
double b = 20.4;
Add<int>(a, b);
return 0;
}
在函数调用时指定模板参数的类型,编译器会进行隐式的类型转换,如果无法类型转换则会报错
#include
using namespace std;
int Add(int left,int right)
{
cout << "int Add(int left,int right)" << endl;
return left + right;
}
template<class T>
T Add(T left, T right)
{
cout << "T Add(T left, T right)" << endl;
return left + right;
}
template<class T1,class T2>
auto Add(T1 left, T2 right) //auto作为返回值,可以推导返回值类型
{
cout << "auto Add(T1 left, T2 right)" << endl;
return left + right;
}
int main()
{
Add(1, 2); //调用int Add(int left,int right)
Add<int>(1, 2); //显式实例化调用调用T Add(T left, T right)
Add(1.1, 2); //调用auto Add(T1 left, T2 right)
Add(1.1, 2.2); //调用T Add(T left, T right)
Add<int,double>(1.1, 2.2);//显式实例化调用调用auto Add(T1 left, T2 right)
return 0;
}
1. 普通函数可以和模板函数同时存在,函数模板还可以被实例化为这个普通函数>
2. 在调用函数时,会选择最为匹配的函数进行调用
- 普通函数和模板函数都存在时,优先匹配普通函数(如果参数类型匹配)
- 没有普通函数,优先匹配函数模版+参数类型匹配
- 只有任意一种,如果类型转换一下也能用,也可以匹配调用
3. 普通函数默认可以进行隐式类型转换,而函数模板不可以
template<class T1,class T2,...,class Tn>
class A
{
public:
///...
private:
T* _arr;
int _top;
int _capacity;
};
注意:类模板只能显式实例化
#include
#include
using namespace std;
int main()
{
stack<int> s1;
return 0;
}