把类型参数化来产生一系列类或函数的机制。用来设计与数据类型无关的通用算法。
函数模板
template<类型形式参数表>
返回值类型 函数名(形式参数表) {
//函数体
}
<类型形式参数表>通过class或typename来指定类型参数
函数模板只是说明,需要实例化为模板函数后才能使用。
函数模板实例化:
- 显式实例化:函数名<实参类型>(实参)
- 隐式实例化:函数名(实参),自动推导出实参的类型
函数模板声明也要加上template<类型形式参数表>
函数模板实例化时不支持数据类型的自动转换。可以通过强制类型转换来解决。
重载函数模板
- 函数模板和普通函数都可以调用
- 多个函数模板都可以调用
编译器会自动选出最合适的,普通函数能匹配就先选普通函数。如果只想使用函数模板,可以在调用函数时加<>空参数列表。
编译器会对函数模板进行两次编译,在声明的地方对函数模板本身进行编译。在调用的地方对参数替换后的模板函数进行编译。
类模板
template<类型形式参数表>
class 类名{
};
类模板实例化而成的类成为模板类。类模板不能进行自动参数推导。
成员函数
- 类的成员函数在运行时才会创建出来。
-
在类的内部声明或实现成员函数时不需要加template<类型形式参数表> 。成员函数在外部实现时必须要加template<类型形式参数表> 。且类模板限定符也要加<T,T1…>
- 要注意,模板类中函数的声明和实现必须放在同一个.h文件内!(函数模板实例化为模板函数时,在预处理阶段,编译器会根据main函数中的函数模板调用,生成一个具体类型的模板函数。如果分开编写,编译器在预处理阶段可以找到该函数模板的声明,不会报错。因为编译器认为该函数模板的实现在其他文件中,在链接时可以调用其他文件中的该函数。但是链接时在其他文件中的函数模板并没有被实例化,所以就会报链接错误。)
成员模板
类中成员为模板形式。
这个成员大多为类的构造函数,为了可以使用该类的子类对其初始化。
template
class Widget{
template
Widget(U widget) {}
};