赞
踩
目录
1、模板是一个泛型编程的概念,即不考虑类型的一种编程方式,模板分为模板函数和模板类。
2、人们需要编写很多个形式和功能都很相似的函数来实现某些功能只因为类型不同,就需要重载
很多个版本,写起来就比较麻烦,也比较啰嗦,此时,就可以使用模板函数来解决这种问题。
3、模板函数:建立一个通用的函数,其返回值类型,形参的类型都不确定指定
而是采用虚拟类型来代替,对于功能相同的函数,就无须重复写代码
并且模板函数和普通函数长相及使用方法非常类似,唯一的区别,类型参数化。
为什么使用函数模板?
(1)它是类型无关的,因此具有很高的可复用性。
(2)它在编译时而不是运行时检查数据类型,保证了类型安全
(3)它是平台无关的,可移植性
(4)可用于基本数据类型
- template <class T,typename T1>//虚拟类型只对下面一个函数有效,
- T add(T a, T1 b)
- {
-
- }
template 定义模板的关键字
<> 里面存放的叫 类型形参表
typename 和 class 是声明虚拟类型的关键字 告诉编译器 开始声明虚拟类型(typename和class作用一样)
T 和 T1 是声明的虚拟类型 可以定义变量,理解成类型)可以在函数中直接当做普通类型使用。
如下代码:
- #include <iostream>
- using namespace std;
-
- template <typename T>//虚拟类型只对下面一个函数有效,
- T my_add(T a,T b)
- {
- return a+b;
- }
- int main()
- {
- int a = 5,b = 25;
- double c = 11.5, d = 45.2;
-
- cout << my_add(a,b) << endl;
- cout << my_add(c,d) << endl;
- return 0;
- }
结果如下:
两种方式调用:
(1) 第一种: 显式类型推导
函数名 <实际类型1,实际类型2>(参数列表);
如: fun<int>(1,2);
(2) 第二种: 隐式类型推导
函数名(参数);
如: fun(1,2)
代码如下:
- #include <iostream>
- using namespace std;
-
- template <typename T> //虚拟类型只对下面一个函数有效,
- T my_add(T a, T b)
- {
- return a + b;
- }
- int main()
- {
- int a = 5, b = 25;
- double c = 11.5, d = 45.2;
-
- cout << my_add<int>(a, b) << endl; //显示调用
- cout << my_add<double>(c, d) << endl; //显式调用
- cout << my_add(a, b) << endl; //隐式调用
- cout << my_add(c, d) << endl; //隐式调用
- return 0;
- }
运行结果如下:
注意:显示类型推导 实参的类型和推导的类型必须一致。
如果有普通函数和模板函数,在调用时可以用显示调用,省略类型的方式
如:swap<>(1,2)
(1)函数只可以有一种数据类型相匹配。模板有多种类型
(2)隐式推导优先使用普通函数,只有普通函数不匹配才使用函数模板
(3)函数模板只有在调用时,才会构建函数,而普通函数是在编译时。
(4)普通函数调用时候可以发生自动类型转换,而函数模板不行。
和普通函数的重载相似
在同一个作用域,函数名相同参数列表不同的多个函数
参数不同: 个数不同
类型不同
顺序不同
(1)前提条件函数名必须相同
(2)返回值不能决定调用哪个函数体
(3)形参列表的不同才是决定是否重载的重要原因
以下是参数顺序不同的重载
-
- template <class T1,class T2>void swap1(T2 a,T1 b)//参数类型顺序不同构成重载
- template <class T1,class T2>void swap1(T1 a,T2 b)
注意:在函数参数顺序不同的重载中,实例化的时候不可以是相同类型
例如 : swap1<int ,int >(1,2)则没法匹配哪个函数。
以下是参数个数不同的重载
- template <class T1,class T2> void swap1(T1 a,T2 b)
- template <typename T2> void swap1(T2 t)//参数个数不同构成的重载
传入不同的参数,调用不同的版本
如下代码:
- #include <iostream>
- using namespace std;
-
- template<class T1, typename T2>
- void select2(T1 len,T2 *arr)
- {
- int temp = 0;
- for(int i = 0; i <= len-1;i++)//选择排序
- {
- for(int j = i + 1; j < len ; j++)
- {
- if(arr[i] < arr[j])
- {
- temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
- }
- }
- cout << "调用了第一个函数" << endl;
- }
- template<class T1, typename T2>
- void select2(T1 *arr,T2 len)//跟第一个构成重载,参数类型不同,类型顺序
- {
- int temp = 0;
- for(int i = 0; i <= len-1;i++)
- {
- for(int j = i + 1; j < len ; j++)
- {
- if(arr[i] < arr[j])
- {
- temp = arr[i];
- arr[i] = arr[j];
- arr[j] = temp;
- }
- }
- }
- cout << "调用了第二个函数" << endl;
- }
- int main(int argc, char *argv[])
- {
- char arr[10] = {'s','c','d','h','f','u','r','b','q','n'};
- int sizeArr = sizeof(arr)/sizeof(arr[0]);
- select2<int,char>(sizeArr,arr);
- for(int i = 0;i < 10;i ++)
- {
- cout << arr[i] << " ";
- }
- cout << endl;
- cout << endl;
- select2<char,int>(arr,sizeArr);
- for(int i = 0;i < 10;i ++)
- {
- cout << arr[i] << " ";
- }
- cout << endl;
- cout << "Hello World!" << endl;
- return 0;
- }
运行结果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。