小伙伴们大家好啊,停更了两个月深表歉意,作者调整好了状态,今后将继续为大家分享C++的相关知识。
在前面的模板初阶中,我们介绍了模板的基本类型以及用法,包括函数模板和类模板,本文我们讲对模板进行更深入的讲解。
一.非类型模板参数
在之前的用法中,我们模板的形参都是类型名,即class T,这种叫类型形参。那么非类型形参就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可以直接把这个参数当成常量使用,比如下图中的N
其中,非类型模板参数有一定的要求,在C++20之前,我们只允许整型的非类型模板参数,在此之后各类型都可以了(只限于内置类型)。那么这个东西有啥意义呢? ——假设我现在写一个静态栈
其中,N我们通过define来控制,我想让st1存10个,st2存100个,那么N只能取100,但对于st1又太大了,所以,我们可以增加一个非类型模板参数,我们可以通过传参来自由控制大小。当然,也可以给缺省值这样我们就不用传参就可以使用了。
二. 模板的特化
1.函数模板特化(谨慎使用)
有些时候,我们可以通过函数模板来进行操作得到我们想要的结果,但有时候同一个模板放在不同的场景下可能就得不到我们想要的结果。我们来看以下场景,假设我们写一个比较大小的函数模板
我们可以用这个函数模板来比较两个日期的大小(假设我们的日期类已经写好),但是,如果用这个模板去比较两个日期指针变量的大小就得不到我们要的结果,为了解决这个问题,我们引进了模板特化这个概念。
对于日期指针的比较,就会走上面的模板(template<>不可省略),而其他的比较就会走我们的通用模板。
2.类模板特化
道理与函数模板特化类似 我们走int ,char类型的data(d1)就走下面这个特化,d2就走类模板
以上均属于全特化
3.偏特化
顾名思义就是不完全特化参数
对于这个偏特化模板,只要变量传入的第二个参数是int类型就会走这个偏特化, 不然就会走其他模板(全特化或者原模板)
三 . 模板的分离编译
什么叫分离编译?
一个程序由若干个源文件共同实现,而每个独立的源文件单独编译生成目标文件,最后将所有目标文件链接起来形成单一的可执行文件的过程称为分离编译模式。
在我们之前的文件中,各个函数的声明都放在了.h文件中,定义放在了.cpp文件中,那么模板是不是也可以实现声明与定义分离呢?答案是no!
因为模板并没有实例化,在调用的时候找不到其模板的链接,但我们可以通过显示实例化的方法让其运行起来,但风险很大。因此模板声明和定义最好不要分开写。而对于类模板,有太长的成员函数可以把定义写在类的外面(不要写在两个文件),短的直接在类中定义即可。
正文结束