函数模板和类模板 模版特化
关键字: template <class t>, template <typename t>
模板
模板(template)是一个将数据类型参化的工具,它提供了一种将代码与数据类相脱离的机制,即代码不受具体的数据类型的影响。模板分为函数模板和类模板两种。
(1)函数模板
函数模板是一种不说明某些参数的数据类型的函数。例如,下面定义了一个可对任何类型变量进行操作(求绝对值)的函数模板:
- template <class T> //或写成: template <typename T> 函数参数的类型T
- T abs(T val)
- {
- return val<0 ? -val : val;
- }
在template语句与函数模板定义语句之间不允许有别的语句。如下面的声明是错误的:
template<class T>
int I; // 不该出现在此位置
T min(T x,T y)
{
//函数体
}
在函数模板被调用时,编译器根据实际参数的类型确定模板参数T的类型,并自动生成一个对应的函数,即模板函数。模板参数的类型不同,生成的模板函数也不同。
模板函数类似于重载函数,但两者有很大区别:函数重载时,每个函数体内可以执行不同的动作,但同一个函数模板实例化后的模板函数都必须执行相同的动作
例 1 函数模板的定义和使用
- #include <iostream.h>
- template <class T> //定义模板
- T abs(T val) //定义函数模板
- {
- return val<0 ? -val : val;
- }
- void main()
- {
- int i=100;
- cout <<abs(i)<<endl; //类型参数T替换为int
- long l=-12345L;
- cout <<abs(l)<<endl; //类型参数T替换为long
- float f=-125.78F;
- cout <<abs(f)<<endl; //类型参数T替换为float
- }
定义函数模板时也可以使用多个类型参数,这时每个类型参数前面都要加上关键字class或typename,其间用逗分隔,其形式如下所示。
template <class T1,class T2,class T3>
例 2 使用多个类型参数的函数模板
- #include <iostream.h>
- template <class T1,class T2>
- T1 Max(T1 x,T2 y)
- {
- return x>y ? x: (T1)y;
- }
- void main()
- {
- int i=100;
- float f=-125.78F;
- cout <<Max(i,f)<<endl; //类型参数T1替换为int,T2替换为float
- }
(2)类模板
使用多个类型参数的类模板
- #include <iostream.h>
- template <class T1,class T2> //使用2个类型参数 类的数据变量参数类型T
- class MyTemClass //定义类模板
- {
- private:
- T1 x;
- T2 y;
- public:
- MyTemClass(T1 a,T2 b) { x=a;y=b; } //构造函数
- void ShowMax() //输出最大的数据成员
- {
- cout <<"MaxMember="<<(x>y?x:y)<<endl;
- }
- };
- void main()
- {
- int a=100;
- float b=123.45F;
- MyTemClass<int,float> mt(a,b); //声明类模板的对象
- mt.ShowMax();
- }
(3)模版特化
模板的“特化”(实例化),它发生在编译期,
无论一个模板被实例化多少次,都不会影响最终结果,但是这会浪费编译的时间.
不知道隐式特化是啥东西.但是显式特化的意思是:当一类东西中出了一渣滓的时候,为了对外接口的统一,或者说是为了家丑不可外扬,有必要把它单独拿出来写一下,然后使他可以和这个类中的所有东西步伐一致。
为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理, 是为模板的特化.
template <class T>
class A {};
template < > class A<bool> { //…// };
上述定义中template < >告诉编译器这是一个特化的类模板