template<typename T>
T Sum(T a, T b)
{
return a + b;
}
1.函数模板:上面定义的模板为函数模板 <>模板的参数列表
编译:定义点:只编译模板的头部 调用点:编译模板体(编译模板实例化后的模板函数)
替换的过程:模板的实例化
2.模板实例化:调用函数模板生成函数的过程(用参数列表中的类型替换该函数中所有的虚拟类型)(该替换为typedef替换:替换后会类型检查)
用 int 实例化模板
int Sum(int a,int b)
{
return a + b;
}
3.模板函数:模板实例化后的函数为模板函数
上面的函数就为模板函数
4.模板实参推演:
调用点:sum(10,20);运行成功,10,20 推演出int型T
限制:
1.不能让编译器产生二义性( 比如: Sun(10.1,20);运行失败,模板类型T不明确)
2.必须有实参才可以推演
int main()
{
Sum<int>(10,20); //正常调用
Sum(10,20); //success
Sum(10.1,20); //error
return 0;
}
5.模板类型参数(class或typename在这里没有任何区别)
6.模板非类型参数 <>中不仅能存放模板类型参数(类型参数),也可以存放非类型参数
1.非类型参数必须为常量
template<typename T, int LEN>(调用点传参后,函数中LEN相当于函数参数,可以直接使用)
Sort2(arr,len) len在定义点必须定义为const类型,即len是一个常量,否则编译不通过
2.float double不能用
7.模板特例化
完全特例化 函数模板只支持完全特例化
参数为char* 时,const关键字应该加到和参数之间,否则会和模板起冲突
(模板中const修饰a,特例化中const修饰a)
bool Comepare(const T a,const T b)
{
return a > b;
}
template<> //特例化需要前加template关键字
bool Comepare<char*>(char* const a,char* const b) //char* 特例化
{
return strcmmp(a,b) > 0;
}
8.默认值
函数模板默认值:C++11以后才有
类模板的默认值:C++98以后才有
使用:直接在模板参数后面用=对其进行赋值(与函数默认值的使用方式一样)
任意赋予:不需要遵循函数默认值的限制,可以对多个类型任意一个或几个赋默认值
模板默认值不能推演
template<typeneme T,int a = 10,char b = 'n',double c>
//合法,模板默认值不需要从参数列表后面开始赋值
9.模板重载(优先级:普通函数>模板特例化>模板函数)
显示调用特例化版本:在调用点使用特例化版本的函数名
10.auto (用来接受不明确类型的返回值)
根据后面的类型 自适应改变本身类型
11.模板的显示实例化
模板的实现一般是在.h文件中
普通函数 声明.h 实现.cpp