C++模板和模板的特化,模板的扩展和智能指针------(14)

模板

概念

模板的作用是实现类型通用,降低代码的冗余度
模板可以为一种算法定义不同类型的版本

实现机制:

复制代码使用类型参数突破类型的限制,丧失一定的类型安全
模板需要实例化才能使用,实例化由编译器完成

模板的分类

函数模板
函数模板就是带类型参数的函数,函数的返回值,形参,局部变量都可以使用类型参数,函数模板支持类型推断(形参)。
rust复制代码函数模板 -----> 实例化 -----> 函数
编译

类模板

类模板就是带类型参数的类,类的成员变量,成员函数…可以使用类型参数,类模板不支持类型推断。
rust复制代码类模板 -----> 实例化 -----> 类 -----> 实例化 -----> 对象
编译 运行

模板的使用

函数模板

语法:
arduino复制代码//函数模板的声明
template类型参数/…>
返回值类型 函数模板名(形参列表)
{
…//可以使用T作为类型
}

//函数模板的调用
函数模板名<类型…>(实参);
//如果函数模板的类型参数可以通过实参来判断,传递的类型可以省略

练习:
使用函数模板实现一个数组的排序,实现数组元素类型的通用
arduino复制代码void mysort(int *arr,int n);

类模板
语法:
arduino复制代码//类模板的声明
template 类型参数/…>
class 类模板名{
//…类中可以直接使用T类型
};

//类模板的使用
类模板名<类型…> 对象;
//类模板不支持类型推断

模板的特化
如果模板第某些特殊类型的行为需要重新定义,此时可以进行模板的特化。
函数模板的特化
语法:
arduino复制代码template <>
返回值类型 函数模板名<特化类型…>(参数列表)
{
//…重定义特化类型的行为
}

//编译器在对函数模板实例化时,如果有特化模板,有限选择特化的模板实例化
//函数模板不允许特化一部分参数,必须全特化

类模板的特化(全类特化)
语法:
arduino复制代码template <>
class 类模板名<特化类型…>{
//…类中的内容重定义位特化类型的行为
};

练习:
为排序类模板实现const char *的特化
类模板的成员特化
对于类模板而言,既可以进行全类特化,也可以只针对部分与特化类型相关的成员函数进行特化。成员函数特化时要保持特化接口和原通用模板一致。
语法:
arduino复制代码//类外进行成员特化
template <>
返回值类型 类模板名<特化类型…>::成员函数名(形参列表)
{
//…使用特化类型重定义函数的行为
}

类模板的局部特化
针对有多个类型参数的类模板,可以只特化其中一部分参数,编译器优先选择特化程度最高的版本。
特化一部分参数
arduino复制代码template
class xxx{…}

//局部特化
template
class xxx{…}

template
class xxx{…}

xxx a; ------ 选择第三个版本进行实例化
xxx b; ------- 选择第二个版本进行实例化
xxx c; ------ 选择第一个版本进行实例化

//对于有多个类型参数的类模板,可以对部分参数进行特化
//编译器优先选择特化程度最高的版本

特化类型参数之间的关系
arduino复制代码template
class xxx{…}

//局部特化
template
class xxx{…}

template
class xxx{…}

//对于有多个类型参数的类模板,可以对类型参数的关系进行特化
//编译器优先选择特化程度最高的版本

针对指针和数组类型的特化
arduino复制代码template
class xxx{…}

//局部特化

template
class xxx{…}

template
class xxx{…}

//对于有多个类型参数的类模板,可以针对指针和数组类型进行特化
//编译器优先选择特化程度最高的版本

作业:

1.使用函数模板和类模板(函数对象)实现二分查找,同时为函数模板实现const char *的特化,类模板实现const char *的成员(查找的成员函数)特化。


模板参数的默认值,非类型参数和模板参数

模板参数的默认值

1.类模板的参数可以有默认值,有默认值的类型参数必须靠右
  如果实例化不提供参数的类型,就使用默认值 
2.右边类型参数的默认值可以是左边的类型参数  

类模板的非类型参数

1.类模板可以接收非类型参数
2.非类型参数只能是常量,常量表达式,常属性的变量
3.非类型参数也可以有默认值
4.函数模板也可以接收非类型参数和默认值     

以下了解的可以了实际开发可能用不到

模板的模板参数

模板除了可以接收类型参数和非类型参数以外,也可以接收模板作为参数,语法如下:

template