http://blog . csdn . net/陈一鸣_1990/article/details/10526371
如果有好文章,
最近看到模板的特殊化,突然想起了显性具体化、隐性具体化、特殊化、部分特殊化、具体化等概念。,这让我头晕。我在网上搜了很多帖子才搞清楚概念。
首先,我会整理我在网上找到的信息。
看了这么多名字,其实有三个。
1.显示实例化
2.隐式实例化
3.专业化(=具体化),部分专业化
一、实例化
1.显式和隐式实例化
什么是实例化:通过用具体值替换模板参数,从模板生成普通类、函数或成员函数的过程。
显示实例化:通过名称可见,它清楚地表明您想要实例化的类型
隐式实例化:通过编译器自己的推测来确定要实例化的类型。
例如,模板:
模板<。classT>。//函数模板实现
空隙交换(T & amp美国电话电报公司;b)
{
Ttemp
temp = a;
a = b;
b = temp
}
A.显示实例化
模板作废交换<。int>。();//这个函数不需要重写函数体,只是一个声明
为什么要显示实例化?
主要是为了提高效率,在显式实例化模板的时候,在使用模板之前,编译器会根据指定的显式实例化类型生成一个模板实例,相当于这个程序中的一个
void swap(int & amp;a,int & ampb)
{
inttemp
temp = a;
a = b;
b = temp
}
这样,当需要调用swap(a,b)时,每次都会重新生成这种类型的代码,这样可以节省空,提高效率。这就是为什么应该显式实例化它。
B.隐式实例化
隐式实例化意味着编译器在使用模板之前不会生成模板的声明和定义实例。只有当使用模板时,编译器才会根据模板定义生成相应类型的实例。
inti=0,j = 1;
swap(i,j);//编译器隐式生成swap(int & ampa,int & amp;b)功能定义。
隐式实例化是指程序员为了省事,省略了类型供编译器判断,这是懒惰的表现。
第二,专业化
1.专业化
但是通常会有一些特殊的情况,不能用泛型模板直接实现。这时就需要为一个特殊类型或者一个特殊类型实现一个特殊的模板,也就是模板特殊化
当t是结构类型时,不能进行交换,所以我们专门针对这种特殊情况写了一个函数,只有当t是结构类型时,才会调用这个专用函数
//到函数
#定义MAXNAME 128
structjob
{
charname[MAXNAME]:
intsalary
};
模板<。classT>。
空隙交换(T & amp美国电话电报公司;b)
{
Ttemp
temp = a;
a = b;
b = temp
};
模板voidswap<。int>。(int & ampa,int & ampb);//显式实例化,只需声明
模板<。>。voidswap<。job>。(job & ampa、工作与收入。B)//显式具体化(如上所述,要区别于实例化,必须定义)
{
intsalary:
薪水= a .薪水:
a .薪资= b .薪资;
b .工资=薪水;
};//显式专门化。
//对于类模板:
模板<。classT>。
类别数组
{
私人:
T * ar
国际号码;
...
};//模板类声明。
模板类数组& ltint>。;//显式实例化。显式实例化
模板<。>。classArray<。job>。
{
私人:
job * ar
国际号码;
};//explicitspecialization。显式具体化,类定义体可以不同于类模板数组
2.部分专业化
模板的部分专门化意味着需要根据模板的一些参数进行专门化。
A.类模板的部分专门化
比如c++标准库中类向量的定义
模板<。类,类分配器& gt
class vector {//…//};
模板<。class分配器& gt
classvector<。分配器& gt{//…//};
//在这个特殊的例子中,一个参数绑定到bool类型,而另一个参数仍然需要由用户指定。
B.函数模板的部分专门化
在网上看到有人说:严格来说,函数模板不支持部分特殊化(这个我不是很懂),但是因为函数可以重载,所以可以达到类似类模板部分特殊化的效果。
例如:
a)模板<。T级>void f(T);
过载a)根据过载规则
b)模板<。T级>void f(T *);
如果a)称为基础模板,那么b)称为基础模板a)的重载,而不是a)的部分专门化。
这里就不深入分析专业化了。
三、模板匹配顺序
1.类模板的匹配规则
例如:
模板<。classT>。class vector {//…//};// (a)普通类型
模板类向量<。typename>。;// (b)的显式实例化
模板<。classT>。classvector<。T*>。{//…//};// (c)指针类型的专门化
模板<。>。classvector<。void* >{//…//};// (d)专门化void*
每种类型都可以作为一般类型(a)的参数,但只有指针类型可以作为(b)的参数,只有void*可以作为(c)的参数
因此,当一个模板类被调用时,首先,找到一个显式实例化的,如果不匹配;然后,找到专门化的,再找到部分专门化的,最后根据模板隐式实例化
2.函数模板的匹配规则
例如:
void swap(int & amp;a,int & ampB){}//普通函数
模板<。>。掉期<。int>。(int & ampa,int & ampB){}//专用模板函数
模板voidswap<。int>。(int & ampa,int & ampb);//显式实例化,只需声明这个
模板<。classT>。空隙交换(T & amp美国电话电报公司;B){}//模板
上面写的顺序是模板的调用顺序。
觉得这篇文章有帮助?请与更多人分享
关注CPP开发者
查看更多精选的C/C++技术文章
↓↓↓
1.《实例化 模板显式、隐式实例化和(偏)特化、具体化的详细分析》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《实例化 模板显式、隐式实例化和(偏)特化、具体化的详细分析》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/guoji/1610755.html