模板特化:实例化模板时,对特定类型的实参进行特殊处理,即实例化特殊的实例版本。
当模板与定义特化的形式参数一起使用时,将调用特化版本。 模板特化分为全特化和部分特化;
1、函数模板特化只能是完全特化;
//通用版本
int(常量 T &v1,常量 T &v2)
如果(v1 < v2)-1;
如果(v2 > v1)1;
0;
对于这个函数模板,当实际参数是两个char指针时,比较的是指针的大小,而不是指针指向的内容的大小。 这时候就需要定义一个专门版本的函数模板,即经过特殊处理的版本:
//为实际参数类型const char *提供专门版本
int (const char * const &v1, const char * const &v2)
(v1,v2);
a: //空模板参数列表
b: //模板名称后面指定特化时的模板参数,为const char * 类型。 也就是说,当使用实际参数类型 const char * 调用函数时,将生成模板的专用版本而不是通用版本。 还可以为其他指针类型(例如 int *)定义专用版本。
c: (const char * const &v1, const char * const &v2)//可以理解为:const char * const &v1,不带const修饰符,实际类型为:char *&v1,即v1是引用一个指向 char 指针的引用,即指针的引用,加上 const 修饰符,v1 就是一个指向 const char 指针的 const 引用,对 v1 的操作就是对指针本身的操作,而操作方法与指针相同,如*v1,是正确的; //注意这里的const char *。 由于形参是指向指针的const引用,因此调用专门版本时的实际参数指针类型(不是存储数据的类型)可以是const或非const。 ,但由于这里形参指针指向的数据类型是const char *(强调存储的数据是const),所以实参指针指向的数据类型也必须是const,否则类型不匹配;
//特殊版本(int *)
int(const int * const &v1, const int * const &v2)//v1和v2是指向const整型变量的const引用;
if(*v1 < *v2) -1;//像指针一样操作,可以理解v1和v2是指针,因为它是指针的引用;
如果(*v2 > *v1)1;
2、与其他函数声明一样,模板特化的声明应包含在头文件中,并且该头文件应包含在使用特化模板的源文件中;
请注意,调用函数模板时,实际参数和模板参数不会进行常规转换。 专用版本和通用版本都不经过常规转换。 类型必须完全一致。 非函数模板在调用实参时进行常规转换; 普通函数和函数调用模板时的实参和模板参数都会经历两次转换:
(1). const 转换:可以分别使用指向非常量对象的引用或指针来调用接受 const 引用或 const 指针的函数,而无需生成新实例。 如果函数接受非引用类型或非指针类型,则形参类型和实参类型会忽略 const,无论将 const 或非 const 对象传递给非引用的函数,都使用同一个实例类型;
(2)。 数组或函数指针的转换:如果模板参数不是引用类型,则对数组或函数类型的实参进行常规转换。 将数组转换为指向实参第一个元素的指针,函数实参视为指向函数类型的; 注意:在函数模板中,模板参数列表中的非类型参数遵循一般转换原则。
--------------------------