泛型编程
泛型编程允许编写与类型无关的代码,从而实现代码的重用。模板是泛型编程的基础,通过编写模板函数或模板类来实现类型无关的逻辑。
函数模板
函数模板代表一个函数家族,与类型无关。实际使用时,模板通过传递不同的类型参数生成具体的函数版本。
template<typename T1, typename T2, ..., typename Tn> |
-
template
和typename
为关键字。 -
T1
,T2
, …,Tn
为模板形参名字,typename
也可以用class
替代,但建议使用typename
。
调用方法:
-
显式类型推导:
template<typename T>
void func(T param) {
// 函数实现
}
// 调用
func<int>(10); // 显式指定类型为 int -
隐式类型推导:
template<typename T>
void func(T param) {
// 函数实现
}
// 调用
func(10); // 编译器根据实参推导类型为 int
普通函数与函数模板比较:
-
数据类型匹配:普通函数只能处理一种数据类型,而函数模板可以处理多种数据类型。
-
优先级:隐式类型推导优先使用普通函数,当普通函数不匹配时才使用函数模板。
-
构建时间:函数模板在调用时构建,普通函数在编译时已构建完成。
-
类型转换:普通函数支持自动类型转换,而函数模板不进行自动类型转换。
类模板
类模板用于定义那些数据成员和成员函数类型不同的类。模板本身是蓝图,编译器用模板生成特定类型的类。
编译阶段:
-
模板定义检查:
- 检查模板定义的语法和逻辑错误,例如遗漏的分号。
-
模板实例化检查:
- 在实例化期间,编译器检查所有调用的有效性,确保实例化的类型支持所需操作。
|
总结
-
函数模板:用于定义泛型函数,支持显式和隐式类型推导,可处理多种数据类型。
-
类模板:用于定义泛型类,编译器生成特定类型的类,编译过程包括定义检查和实例化检查。