常规的编程函数设计
以往我们程序员设计两个参数交换的函数时候简单的会使用如以下方式
void Swap(int& left,int& right)
{int tmp=left;
left=rigth;
right=tmp;
}
//面对不同类型的参数时
void Swap(short& left,short& right)
{int tmp=left;
left=rigth;
right=tmp;
}
这时我们一旦涉及到新的参数类型时我们要手动添加新的函数,这样代码复用率低的同时,还增加了我们手动的操作繁琐度。
而C++提供模板类型,让这种情况得以缓解。
以template<typename T1,typename T2,.....,typename Tn>为开头
返回值的类型 函数名(参数列表){ 函数体 }
为一个结构,如以下
//typename是定义模板参数的关键字,也可以用class代替
//template<class T>
template<typename T>
void Swap(T& left,T& right)
{
T tmp=left;
left=right;
right=tmp;
}
当我们有两组数据,分别是int类型和double类型的时候,我们使用模板函数就可以一次解决两个问题而不是像最前顶上的编程方法,给每一个类型都制作独属的函数体。
typename 的 T会被要使用的类型参数替换。如果要使用int,模板会进行以下操作,如
template<typename T>
void Swap(T& left,T& right)
{
T tmp=left;
left=right;
right=tmp;
}
//更换成为如下
template<typename T>
void Swap(int& left,int& right)
{
int tmp=left;
left=right;
right=tmp;
}
实例化
模板有有两种实例化的方式:隐式和显式
隐式实例化
1:隐式实例化的效果是:让编译器根据提供的实参进行推演模板参数的实际类型。
template<typename T>
void Add(T& left,T& right)
{
return left+right;
}
int main()
{
int a=10,int b=20;
double d1=20.0,d2=30.0;
Add(a1,a2);
Add(d1,d2);
}
但是上述中Swap(a1,d1);是行不通的,因为模板参数列表中只有一给T
编译器无法给T定义为int或者double,就会报错
如果一定要进行编译通过可以自己进行强制转换
如:Add(a1,(int)d1);
显示实例化
在函数名后面的<>中只当模板参数的实际类型
如
template<typename T>
void Add(T& left,T& right)
{
return left+right;
}
int main()
{
int a=10;
double s=20.0;
Add<int>(a,b);
}
类模板
template<class T1, class T2, ..., class Tn>
class 类模板名
{
// 类内成员定义
};
#include<iostream>
using namespace std;
// 类模版
template<typename T>
class Stack
{
public:
Stack(size_t capacity = 4)
{
_array = new T[capacity];
_capacity = capacity;
_size = 0;
}
void Push(const T& data);
private:
T* _array;
size_t _capacity;
size_t _size;
};
template<class T>
void Stack<T>::Push(const T& data)
{
// 扩容
_array[_size] = data;
++_size;
}
int main()
{
Stack<int> st1; // int
Stack<double> st2; // double
return 0;
}
//注意
//类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的
//类型放在<>中即可,类模板名字不是真正的类,而实例化的结果才是真正的类
// Stack是类名,Stack<int>才是类型
Stack<int> st1; // int
Stack<double> st2; // double