模板函数与模板类
一.模板函数
1.模板函数的基本使用
<span style="font-size:18px;">template<class T> T Max(const T& ValueA,const T& ValueB)
{
return ValueA > ValueB ? ValueA : ValueB;
}
template<class T,class T1> T MaxEx(const T& ValueA,const T1& ValueB)
{
return ValueA > ValueB ? ValueA : ValueB;
}
template<class T> T GetValue()
{
return 10;
}
template<class T1,class T2,class T3> T1 Add(const T2& ValueA,const T3& ValueB)
{
return ValueA + ValueB;
}
template<class T,int nMaxSize> T* MyNew()
{
return new T[nMaxSize];
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRelt;
nRelt = Max(5,8); <span style="color:#ff0000;">//知识点1:模板函数具有类型推断功能,可以根据你传入的参数的类型推断编译该函数为什么类型的函数</span>
printf("%d\n",nRelt); //输出8;
//nRelt = Max(5,8.1);<span style="color:#33cc00;">//注意点1:error! 编译出错,系统无法判断您要比较的类型是int还是double
</span>
nRelt = Max<int>(5,8.1);<span style="color:#ff0000;">//知识点2 : 强制将所有传入参数类型设置为int,即:系统编译后将8.1编译为8;</span>
printf("%d\n",nRelt);//输出8;
nRelt = MaxEx(5,8.1);<span style="color:#ff0000;">//知识点3: 在模板类中可以加入多个类型以表示要各个要传入参数的类型</span>
printf("%d\n",nRelt);//输出8;
//nRelt = GetValue();<span style="color:#006600;">//注意点2: error! 系统在编译该函数时,根本不知道你反回的是什么类型,编译器不管你的实现,所以无法生成对应的函数</span>
nRelt = GetValue<int>(); //OK; 您显式的告诉系统在编译的时候将类型设置为int;
//nRelt = Add(100,3.14);//error ! 原因就是注意点2
nRelt = Add<int>(100,3.14); //Ok; 强制将返回类型设置为int,即为知识点2;
int* p;
int a = 10;
//p = MyNew<int,a>();<span style="color:#ff0000;background-color: rgb(255, 255, 255);">//知识点3:error! 如果在函数定义时,已经明确为普通类型参数,则1:在函数实现中不能改变该值,如nMaxSize++;</span>
return 0;//2 :只能传入参数类型对应的常量,不能传入变量
}</span>
2.模板函数的特化与偏特化
特化原因: 模板函数内部无法实现某些特殊类型的参数,所以需要特殊化;
例如上面的函数max函数,如果你这么使用:
char* p;
p = Max("abc","cde");//error! 为什么?因为传入的是常量,而Max函数要求传入变量的引用,这样字符串的比较是不是就有问题了?
p = Max("abc","cde");//error! 为什么?因为传入的是常量,而Max函数要求传入变量的引用,这样字符串的比较是不是就有问题了?
知识点1:特化就是说对于某些特殊类型的参数,如果要使用模板函数,但无法满足
1)正确传入参数
2)实现中无法和其他类型的参数使用同样的方式,则需要特殊写出该函数;
针对上例模板函数特化:
char* Max(char* p1,char* p2)
{
return p1 > p2 ? p1 : p2;
}
知识点2 : 特化是针对某种类型,偏特化是针对某部分类型;
上面特殊化时只特殊化了char*类型,那如果Max函数要使用int或者double类型指针呢?
此时我们知道,这些参数共同的特性都是指针,此时就需要偏特化,写法如下:
template<class T>
T* Max(T* p1,T* p2)
{
...
}
二.模板类
1.模板类基本使用
1.1 模板类的除了写法与模板函数不同外,模板函数的其他特性与模板类相同;
注意: 类模板只是模板不是类
例如:
template<class T>
class Parent
{
public:
T GetFatherAge()
{
return 50;
}
};
// template<class T>
// class Chlid : public Parent //error ! 注意点1: Parent只是模板并非类
// {
// public:
// T GetSunAge()
// {
// return 10;
// }
// };
template<class T>
class Chlid : public Parent<T> //Ok ;注意点2:只有这样,Parent才是内部类型为T的类;
{
public:
T GetSunAge()
{
return 10;
}
};