什么是模板:
这里只讲函数模板,模板的话就是泛型编程,泛型编程是用一个标志来表示类型,不是实际的类型。独立于任何特定类型的编辑,是C++的一部分,不是全部。
可能很多朋友不明白什么是模板,打个比方。模板就是一个模板一样的,做数学题不会做,有个公式,按照想法套进去就行了。还有PPT,我们使用或者要用PTT,有多少人是一顿骚操作。从零到有创建出来的。其实不然,我们只要一个空白的模板,然后把我们想要的内容制作出来就行了,模板就是最基础的东西。最简单的理解,它就是一个框架,需要填写内容。当然,小伙伴们也知道他的作用了,就是方便开发,写开发就不需要自己想模板了,直接照搬,还有一个作用就是提高复用率。以上就是一个简单叙述,那么接下来就是讲关于它的知识点了。
先给大家讲三个关键字。
template-----声明创建模板
typename--------表明后的类型是一个通用类型,也可以叫虚拟类型(可以用class代替)
T1--------通用类型或者虚拟类型,也是一种类型,可以在函数中直接当做普通函数来使用。
2.函数模板:
格式:template<class T1,typename T2>
返回值 函数名(参数){ }
以上就是模板的一个使用。
函数模板的调用:
第一种: 函数名 <实际类型1,实际类型2>(参数列表);
显式类型推导 fun<int>(1,2);
第二种: 函数名(参数);
隐形类型推导
5.注意:显示类型推导 参数和推导的类型必须一致。
如果有普通函数和模板函数,在调用时可以用显示调用,省略类型的方式 swap<>(1,2)
6.普通函数和函数模板的区别:
函数只可以有一种数据类型相匹配。模板有多种类型
隐式推导优先使用普通函数,只有普通函数不匹配才使用函数模板
函数模板只有在调用时,才会构建函数,而普通函数是在编译时。
普通函数调用时候可以发生自动类型转换,而函数模板不行。
7.函数模板重载
和普通函数的重载相似。也是同一个作用域类函数名相同参数列表不同。
以下是参数顺序不同的重载
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)
传入不同的参数,调用不同的版本
8.函数模板特化
定义:为了解决函数模板的局限性,在定义函数模板时候,直接确定好T的类型。也就是特定的类型模板。
格式: template<class T> 返回值 函数名(类名& 对象){ }
匹配:如果传入的是自定义类型,并且和特化版本匹配,会优先使用特化版本
注意:如果特化后,类型确定才可以使用自定义类型中的成员变量和方法。
9.多文件实现函数模板
在定义函数或者类的时候,会.h和cpp文件,定义和申明分开。
出现连接错误的原因:函数模板是在调用时确定的版本,而调用时.h中没有函数实现,出现连接错误,找不到函数体。
如果分开后,编译会出现连接错误。
第一种办法:在main中#include <xxx.h> 和 #include <xx.cpp>
第二种办法:模板的定义和申明都放在.h头文件中。
10. 函数模板的嵌套
定义:在函数模板中调用另外一个函数模板
11.函数模板的非类型参数
希望传入函数一个特定的确定参数,但不希望放在小括号中。
可以通过非类型参数实现。在模板<>中加了一个参数,但这个参数不是类型参数,是具体的某一个值。
格式:template<class T,基本数据类型 变量名>
返回值 函数名(T& 变量)
例如:template <class T,int size>
void showArr(T* arr);
注意:在上例子中,size是通过模板传入到函数中,可以当做普通变量使用
非类型参数都是常量,在函数中不允许修改,只可以使用,定义非类型参数变量时候,需要加const。
12.类模板
建立一个通用的类,如果希望成员变量的类型是任意的,用类模板实现。
类模板不是一个实际的类型,是虚拟的,和ppt模板一样,实例化的时候才会构建类。
格式:template<typename T>
class test { T age; };
实例化: 类名<类型> 变量名(参数);
类模板和函数模板区别
函数模板可以使用隐式类型推导,但类模板不可以,必须显示推导
类模板在定义template时候,可以加上默认参数。template<class T1,class T2=string>
在模板中的默认参数类型中,如果所有模板参数都是缺省,但在类进行实例化的时候,尖括号不可以省略template<class T1=int,class T2=string>
class person{}; person<> wang(3,"wang");