1.模板定义
模板是对类型进行参数化的工具。
template <class T>
template <typename T>
template、class、typename均是c++中的关键字,上述两种定义方式作用相同。
2.模板分类
1.函数模板
1.函数模板定义
template <class T>
T Add(const T& a, const T& b)
{
return a + b;
}
当调用上述函数时,编译器会根据实参类型推演处T的类型。例如Add(1, 2);
推演T为int类型,Add(1.0, 2.0);
推演T为double类型。
2.多个实参类型不同的情况
Add(1, 2.0);
当两个实参类型不同时,编译器无法推演出T的类型。
有以下两种解决办法:
1.将其中一个实参强制类型转换成和另一个实参相同的类型。
Add(1, int(2.0));
2.显示实例化函数的类型
Add<int>(1, 2.0);
这样编译器可以推演出T为int类型。
3.函数模板原理–模板实例化
当我们通过函数模板调用一个函数时,编译器会自动根据实参类型推导函数类型,该过程称为模板实例化。编译器用函数模板推导出的函数称为模板函数。
事实上我们还调用的是正常的函数,只是该函数是由编译器推出来的,用户只需定义一个函数模板即可。
2.类模板
1.类模板定义
class Stack
{
public:
Stack(int size = 0, int capacity = 15)
:_a(new T[capacity])
,_size(size)
,_capacity(capacity)
{
}
void PushBack(const T& x); //类内声明
void PopBack()
{
}
~Stack()
{
delete[] _a;
_size = 0;
_capacity = 0;
}
private:
T *_a;
size_t _size;
size_t _capacity;
};
//类外定义
template <class T> //声明模板供下面定义函数使用
void Stack<T>::PushBack(const T& x) //类外定义函数指明是哪个类,以及是哪个模板T
{
}
int main()
{
Stack<int> s1;
return 0;
}
几个注意事项:
1.类内声明,类外定义时,一定要在定义前加上模板的声明。且类名后也要加上生命的模板类型
//类外定义
template <class T> //声明模板供下面定义函数使用
void Stack<T>::PushBack(const T& x) //类外定义函数指明是哪个类,以及是哪个模板T
{
}
2.用类模板实例化对象要加类型,该类型相当于是模板的实参,指明T的类型是什么。
Stack<int> s1;
Stack<double> s2;
Stack<char> s3;
也就是说模板类的类型是 Stack<int>
而普通的类类型是Stack