文章目录
- 一、函数模版
- 1、模版的语法
- 2、多个模版类型参数
- 3、模版的实力化
- 二、类模版
- 1、using
- 2、类模版解决问题
一、函数模版
1、模版的语法
模版的关键字为template,后面跟<>尖括号,尖括号里面填类型,类型前面跟一个关键字typename,也可以用class
模版生成的函数就是逻辑一样,就是类型不一样
//template<typename T>
template<class T>
void Swap(T& x, T& y)
{T tmp = x;x = y;y = tmp;
}
在调用时根据不同类型编译器生成一个匹配该类型的函数
2、多个模版类型参数
对于需要不同类型模版也可以实现,需要定义多个参数类型
template<class T1,class T2>
void Swap(T1& x, T2& y)
{T1 tmp = x;x = y;y = tmp;
}
在针对不同类型时也可以使用强转让编译器知道要实例化什么类型的函数
- 注意的是强转后的参数具有常性
template<typename T>
T Add(const T& x, const T& y)
{return x + y;
}int main()
{int a = 1;double b = 3.3;std::cout << Add(a, (int)b) << std::endl;std::cout << Add((double)a, b) << std::endl;return 0;
}
3、模版的实力化
前面编译器自动推导后生成的函数是隐式实例化。
也可以由程序员控制让模版生成什么类型的函数来调用,称为显示实例化。
template<typename T>
T Add(const T& x, const T& y)
{return x + y;
}int main()
{int a = 1;double b = 3.3;//隐式实例化std::cout << Add(a, (int)b) << std::endl;std::cout << Add((double)a, b) << std::endl;//显示实例化std::cout << Add<int>(a, b) << std::endl;std::cout << Add<double>(a, b) << std::endl;return 0;
}
- 在调用时用尖括号<>里面明确了T的类型
显示实例化主要用于编译器无法通过推导生成函数是需要指定类型实例化
template<typename T>
T* New(int n)
{return new T[n];
}int main()
{int* p1 = New<int>(10);return 0;
}
二、类模版
1、using
c++中using可以替换typedef
typedef int STDATATYPE;
using STDATATYPE = int;
使用方式有差异,效果一样
2、类模版解决问题
之前创建栈用typedef来解决存储数据类型的问题,但如果存储了一个类型的数据,就不用用栈存储另一个类型的数据,栈不能进行同时存在多个类型数据进行存储。
所以还是用模版生成栈可以同时存在用来存储不同类型的数据。
template<class T>
class Stack
{
public:Stack(int n = 10){_a = new T[n];_top = 0;_capacity = n;}~Stack(){delete[] _a;_top = 0;_capacity = 0;}
private:T* _a;int _top;int _capacity;
};
- 当然类模版要显示实例化,没有传参的机会
int main()
{Stack<int> st1;Stack<double> st2;return 0;
}