C++模板的偏特化与全特化
全特化和偏特化的概念:
- 全特化:将所有模板参数固定成指定类型,以此来告诉编译器,当为此种类型时,需要特殊处理。
- 偏特化:将部分模板参数固定成指定类型。函数模板是不允许偏特化的,但函数允许重载,从而声明另一个函数模板即可替代偏特化的需要。
直接参考如下链接进行学习:
- 首先通过链接1学习C++模板的偏特化与全特化的知识,其中还介绍了:全特化函数模板时,如果模板形参只在函数形参中出现的话,可以不用指定模板实参;如果模板形参在函数体中出现的话,可以必须指定模板实参;
- 然后还可以从链接2中获取到直接可运行的代码实例进行学习。
链接2里的内容总结:
-
匹配顺序:在模板、模板的全特化和模板的偏特化都存在的情况下,编译器在编译阶段的匹配顺序如下:模板的全特化、模板的偏特化、模板(优先级有高到低)。
-
模板实例化:模板定义本身不参与编译,而是编译器根据模板的用户使用模板时提供的类型参数生成代码,再进 行编译。用户提供不同的类型参数,就会实例化出不同的代码。
-
模板函数不能是虚函数:编译器在编译一个类的时候,需要确定这个类的虚函数表的大小。一般来说,如果一个类有N个虚函数,它的虚函数表的大小就是N,如果按字节算的话那么就是4*N。
如果允许一个成员模板函数为虚函数的话,因为我们可以为该成员模板函数实例化出很多不同的版本,也就是可以实例化出很多不同版本的虚函数,那么编译器为了确定类的虚函数表的大小,就必须要知道我们一共为该成员模板函数实例化了多少个不同版本的虚函数。显然编译器需要查找所有的代码文件,才能够知道到底有几个虚函数,这对于多文件的项目来说,代价是非常高的,所以才规定成员模板函数不能够为虚函数。(参考自:成员模板函数不能为虚函数)
其他
函数重载实现偏特化:
#include<bits/stdc++.h>
using namespace std;
template<class T1>
void func(){
cout<< "template<class T1>" <<endl;
}
template<class T1,class>
void func(){
cout<< "template<class T1,class T2>" <<endl;
}
int main(){
func<int>();
func<int,int >();
return 0;
}