模板格式
template<class T>
T Add(const T& left, const T& right)
{
return left + right;
}
int a1 = 10;
double d2 = 20.0;
类型转化
上述代码若执行Add(a1,d2),就会报错
解决方法有两种
1:强制类型转换
Add(a1, (int)d2);
或Add((double)a1, d2);
2:显示类型转换
Add<int>(a1, d2);
或Add<double>(a1, d2);
模板实例化
类模板与函数实例化不同,在类模板实例化时,需要MyTemplate<int>或者MyTemplate<double>等的具体类型
注意:MyTemplate是类名,不是类型,MyTemplate<int>才是类型
非类型模板参数
用一个常量作为类(函数)模板参数,该参数可以当作常数来使用
template<class T,size_t N=10>
注意:1、浮点数、类对象、字符串不可以作为非类型模板参数
2、非类型模板参数必须在编译阶段确定结果(如果没在编译阶段确定,也就是模板没有实例化,无法通过链接)
模板特化
函数特化
比较两个大小时,如果传正常的参数就可以比较,但是传地址或者其他的就需要函数特化
函数特化步骤:
1、需要一个基础函数模板
2、template后面接一个空<>
3、函数名后面接上<特化类型>
template<class T>
bool Less(T left,T right)
{
return left<right;
}
templast<>//函数特化
bool Less<Date*>(Date* left,Date* right)
{
return *left<*right;
}
类特化
全特化
将模板参数全部确定化
偏特化
有两种
对一部分参数确定化
template<class T1,class T2>
class Date
{
private:
T1 _d1;
T2 _d2;
};
template<class T1>//偏特化
class Date<T1,int>
{
private:
T1 _d1;
T2 _d2;
};
对模板参数进一步限制
template<class T1,class T2>
class Date
{
private:
T1 _d1;
T2 _d2;
};
template<typename T1,typename T2>
class Date<T1*, T2*>
{
private:
T1* _d1;
T2* _d2;
};
模板的分离编译
模板声明与定义分离,在头文件声明,在源文件定义
模板一般会经过两次编译,一次是编译阶段,一次是实例化阶段,所以模板不支持分离编译
这里容易出的找不到链接的问题
一般代码生成需要经过 预处理 编译 汇编 链接
在编译阶段遇到模板的声明,能够通过,但是到链接时,模板没有实例化,就无法找到链接
解决方法:
1、把声明跟定义放在一个.hpp(.h)文件中 推荐使用
2、将模板定义位置实例化