目录
partial specialization(模板偏特化,局部特化)
template template parameter(模板模板参数)(了解)
specialization(模板特化)
所谓的特化,就是泛化(就是模板,用的时候再指定类型就可以了)的反面,那么特化的意思就是,作为一个设计者,很可能面对某些独特的类型,要进行特殊化的处理。所以,非常有可能,在设计完模板之后,在非常局部的地方,将模板针对某些独特的场景,将其特殊化固定下来,
下面看个例子:
其中,key只是一个符号,可以用来代表各自类型, 上图的第一小部分是泛化,第二部分是特化,可以看出模板特化的语法是特征是比较明显的,直接在类中将类型指定出来,没三段都对小括号进行重载,看图上的灰色部分,调用的是模板特化的,因为特化和泛化同时皆可的情况下,优先用特化的。特化可以有任意版本,不限个数。
partial specialization(模板偏特化,局部特化)
偏特化可以分为两个部分,一个是个数上的偏,一个是范围上的偏。
个数上的偏特化
下图的函数模板头部包含两个参数,你想绑定其中一个,比如这个例子中的vector,想指定一下模板类型("typename T"),再指定一个分配器("typename Alloc=...."),你在设计的时候,如果这个元素是bool值的话,是应该有一种独特的设计与之对应的,因为在C++中,最小的模型单元是char啊,这种8个位所形成的字节,如果让一个字节去代表一个Bool值,是有点浪费的(浪费8倍),所以,当客户要求用bool类型的时候,我会去考虑为这个类型单独设计符号去处理,而不是用泛化模板去处理。以这个需求出发,我就要告诉编译器,这儿有两个模板参数, 我只用一个,另外一个(即 "typename T")被我绑定了,剩下的一个"typename Alloc"还没定,所以,仍然要在后面特化的部分写出来。
这就是在个数上的偏特化的语法,说白了,只把模板参数的一部分进行指定,其他的不指定。
而且,绑定参数的过程,必须从左到右,依次进行,不能用跳的。
范围上的偏特化
如果我设计接收T,T是可以代表任意类型,那么,根据实际需要,我需要把T可以代表的类型的范围给缩小,比如,把T变成一个指针类型,至于指针具体指向什么,都可以,但与原来相比,T的可表示范围的确是缩小了,这就是所谓的范围上的偏。
如上图所示,先写一个泛化的,然后,再写一个特化的,将T的范围缩小成一个指针类型,至于指针指向什么,都可以。需要注意的是,不要把T和T*混淆,这两个T没有任何关系!它们一个是泛化,一个是特化。
当使用者如灰色部分去调用的时候去调用的时候,会调用特化的模板。
template template parameter(模板模板参数)(了解)
看标黄的部分,就是一个模板中的模板,
我希望使用者按灰色部分的第一种方式来使用,但这种方式行不通,只能通过第二种方式调用,第二种语法依托第二块内容来实现。
这样设计就可以通过了。使用传进来的一个智能指针,并以T为智能指针的参数。模板模板参数这样的写法,是很高深的,
下面这种情况算模板模板参数吗?
这种写法的时候,是按灰色部分那么用的,第一种预防是指定第一模板参数,如果按第二种写法,就已经不再是模板了,已经把对应的类型给写死了,所以,不能说这种定义方式是模板模板参数。
而对应的之前例子,在使用模板模板参数的时候,并没有将其类型写死。