C++入门6--模板初阶
1.泛型编程
为了引入这个泛型编程,我们先来思考一个问题:如何写出一个通用的交换函数呢,所谓的通用,就是指可以交换整型,浮点型,字符型,以及自 定义 类型呢?
如果我们还没有学C++,那么我们可能Ctrl+C、Ctrl+V去创建很多个函数,但是C++提供了一个很好用的方式,就是给编译器生成一个模子,让编译器根据不同的 类 型来生成不同的函数,即使是自定类型也可以
2.函数模版
2.1函数模版的定义
函数模版在 使用 时里面的类型被实例化,生成特定类型的函数版本
2.2函数模版的格式
template
/ template 返回值类型 函数名 (参数列表)
{
}
2.3函数模版的 原理
函数模版就是给编译器提供一个模子,蛋挞本省不是函数,在调用他的时候,会生成具体类型的函数版本。所以就是编译器帮我们做了很多没有用并且重复度的工作。在编译阶段,编译器会根据实参的类型推演生成对应类型的函数。
2.4函数模版的 实例 化
使用不同类型的参数调用函数模版时,叫做函数模版的实例化,函数模版的实例化分为显示实例化和隐式实例化。
1.隐式实例化。让编译器根据实参来自动推演模版参数的实际类型
1 | template<typename T> |
可以看到我们在调用的时候没有传入T的类型,但是编译器会自动识别并生成对应函数
但是还有其它的情况
1 | template<typename T> |
这样的话就只能把a或者b强转成一个类型。
2.显示实例化:调用函数时,在函数名后面的<>中指定模版参数的实际类型
1 | template<typename T> |
2.5模版参数的匹配原则
1.一个同名的非模板函数可以和一个同名的模板函数同时存在,而且那个模板函数还可以实例化成那个非模板函数
1 | template<typename T> |
补充:编译器的风格是
有符合要求的成品函数就调用成品函数,如果没有的话就使用模板函数。但是如果模板函数和非模板函数都能使用的时候,编译器会优先使用非模板函数。但是你也可以用函数名显示调用模板函数,这样的话,编译器就会调用模板函数而不是非模板函数
2.模板函数不允许自动进行类型转换,但是非模板类型可以自动进行类型转换(也就是说废模板类型可以强制类型转换)
3.类模板
3.1类模板的定义格式
template
class 类名
{
//成员函数
}
1 | template<typename T> |
注意:类模板在定义对象的时候,只能显示定义,不能让编译器自己去隐式推演
eg:Stack
Stack
3.2类模板里面成员函数的定义与声明分离
在指定类域的时候,需要类名+<模板参数>,比如:Stack
1 | template<typename T> |
