一.非类型模板参数
可用来定义常量。定死参数是什么类型,发生**改变的只是参数的值。**支持缺省值。
注:使用缺省值要这么干:

宏和非类型模板参数的区别
如果N是一个宏,那么它只能被定义为一个数,无法在使用时(main函数里)再做变更。而如果N是一个非类型的模板,那么就可以在使用时灵活改变大小。


坑
定死的类型仅限整型(char,int,long,bool,size_t...),double之类的都不可以,自定义类型更不可以。

二.特化
1.函数模板的特化
对函数模板某一特定类型进行具体化。其余类型正常照类模板走。


恕作者实在能力有限,特化着实用起来麻烦,各种const加的混头晕脑,还是利用特定类型实例化一个函数模板来的畅快。

函数特化要谨慎使用!!
2.类模板的特化
①.全特化

②.偏特化/半特化

③.针对指针的偏特化

④.针对引用的偏特化

特化也有惰性,能全特化绝不偏特化。
三.模板声明定义分离会出错的原因
回顾一下编译链接的过程:

解释原因
假设项目由三个文件构成:
Func.cpp,test.cpp,Func.h
两个cpp文件均包含了.h文件
test里有测试用例(实参)
函数模板声明在.h中,定义在Func.cpp中。
模板的实例化发生在编译阶段,随后进入汇编阶段时,会在符号表里生成实例化的函数的地址。最后进入链接阶段,会把上面这个地址链接上。(当然,以上是基于声明和定义在同一文件内的)
如果声明和定义分离到两个文件里,那么负责实例化的定义代码和只负责插个眼的声明代码就在不同文件中。由于test包含了.h,此时就单单一个声明代码进入编译链接的过程,那么这样是没法实例化的。既然没有实例化的定义代码,模板就没法实例化成具体的函数。那么进入汇编阶段时,没有实例化的函数,符号表就没法生成对应的函数地址。
没地址,就没法链接。
为何.cpp文件明明包含.h文件,那代码最后不是声明和定义不就会链接整合到一块了吗,那这个时候不就有实例化的代码了吗?
得注意, 即便包含了, 在最后一步链接之前,整个项目不同文件依旧是独立的。而实例化恰恰就在链接前的编译阶段。