有点绕的两个概念,巩固下~~
函数模板定义
c++融合了三种编程方式:
- 面向过程
- 面向对象
- 基于模板的泛型编程
模板是c++新增的一种特性,它可以通过一次定义来告诉程序你想要什么样的算法函数,然后编译器再根据你输入的参数类型生成对应的函数定义。简单的说,它类似一个我们写英语作文时的模板,面对不同的话题,替换掉对应的关键字就行了,而在c++里,对应的关键字就是参数的类型。当我们想要同一个算法处理int、double等不同的类型,它便能帮助我们省去一些重复的工作。
所以模板只是一个生成函数定义的方案,当编译器使用这个方案来根据参数生成具体的定义时才会产生模板实例。
模板实例化
隐式实例化
前面说到编译器会判断参数的类型,从而生成不同的函数定义。这个自动判断的过程,就是函数偷偷帮你做了,即隐式实例化。但有一点,编译器比较傻,当你给出的参数类型不同时,比如有两个参数,一个是int,一个是double,这时函数就傻眼了,觉得不对不能根据这个模板生成对应的定义。有些情况下可以通过下面的显式实例化来解决这个问题。
显式实例化
命令编译器用某一个类型创建特定的函数定义。
用法:
1 | template <typename T> |
上面是利用Swap模板来生成一个int类型的函数定义
1 | short m = 4; |
上面便是强制生成了int的实例,使用时会强制转换short为int。
模板具体化
使用某个模板定义出一个更具体的模板,优先级大于原先的模板。
用来解决一些特殊的情况,比如还是Swap这个模板
1 | template <typename T> |
对于两个结构时,由于结构允许直接赋值,所以能正常允许,结果是两个结构里所有成员都交换了。
假如我们有这样的需求,只交互里面特定的成员。由于操作对象还是两个结构,所以函数重载便用不上了。
这时候模板具体化就可以帮我们解决这个烦恼,可以使用
1 | template <> void Swap(job &a, job &b) |
两种方式创建针对于job结构的模板,优先级大于普通的Swap
就可以定义一些特殊情况的处理函数了。
总结
实例化是根据模板实例出来的函数定义
具体化则是模板的变体,还是属于模板
所以两者有着很大的不同,用途都是解决一些特殊的情况。