一.模板
①.模板的语法
template
只有template下面的一个函数,是模板
1.模板的定义
#define _CRT_SECURE_NO_WARNINGS
include <iostream>
using namespace std;
//template<class T1, class T2 /*可以写很多*/>
template<typename T>//申明下面的第一个模板函数
void MyAdd(T& a, T& b)
{
return a + b;
}
2.模板的参数
模板参数可以是
- 类型参数(如int,float)
- 非类型参数(用关键字声明的类型)(如typename T,此时T就是个类型)
注: 非类型参数可以是整型、指针或引用,通过常量表达式传递)
②.模板的特点
特点1 : 减少重复性的函数定义
通过将数据类型作为参数传递给模板函数,自动生成对应的函数代码。这种方式可以避免写重复的代码
特点2 : 两次编译
- 第一次编译函数模板
- 第二次产生已经实例化的模板函数,对第二次模板函数进行编译
特点3 : 函数模板的重载
补 : 重载的概念
-
重载指的是在同一作用域内,可以定义多个名称相同但参数列表不同的函数,编译器会根据调用函数时实际传入的参数类型和数量来选择最匹配的函数
-
首先函数模板可以与普通函数构成重载关系,但在调用时,编译器会优先调用普通函数,而不是函数模板
-
函数模板不允许自动类型转化
-
普通函数允许自动进行类型转化
补 : 自动类型转化
```
int MyAdd(int a, int b)
{
return a + b;
}
int mian()
{
int x = 10;
char c = 'a';
int o = MyAdd(x, c);
printf("%d", o); // o = 106
//该函数调用中,自动将char类型转化成int类型
//即自动化类型转换
return 0;
}
```
总结 :
模板函数不能进行类型转换,所以相重载时,如果传入的参数类型,不够符合模板函数的参数类型,就不会使用函数模板,在模板函数和普通函数需要传入参数相同时,优先调用普通函数 ---- 模板函数需要精确的类型
特点4 : 函数模板的实例化
“<>” : 在调用时,增加一个尖括号,就会在参数足够匹配的情况下,选择模板函数
int o = MyAdd(x1, x2);//此时是调用普通函数
int o = MyAdd<>(x1, x2);//此时调用模板函数
③.模板的产生过程
补:编译的过程
1 .c文件经过预编译器变成 .i文件
2 .i文件经过编译器变成 .s文件(汇编文件)
3. .s文件经过汇编器变成 在linux中是 .o(在windows中是 .obj)文件(目标文件)
4. .o(.obj)文件经过连接器,进行链接变成可执行程序 .exe文件
编译的三个步骤 E(编译) S(汇编) c(链接),和键盘右上角一样,前两个大写,最后一一个小写
过程
1 .函数模板 -> 模板函数
2. 根据传入的T生成,特定的模板函数
3. 根据实际的调用情况,生成函数,相同的函数只生成一次