C++模板的特化详解(函数模版特殊,类模版特化)
代码上传⾄
或者
参照
模版与特化的概念
函数模版与类模版
C++中模板分为函数模板和类模板
函数模板:是⼀种抽象函数定义,它代表⼀类同构函数。
类模板:是⼀种更⾼层次的抽象的类定义。
特化的概念
所谓特化,就是将泛型的东东搞得具体化⼀些,从字⾯上来解释,就是为已有的模板参数进⾏⼀些使其特殊化的指定,使得以前不受任何约
束的模板参数,或受到特定的修饰(例如const或者摇⾝⼀变成为了指针之类的东东,甚⾄是经过别的模板类包装之后的模板类型)或完全
被指定了下来。
模板特化的分类
针对特化的对象不同,分为两类:函数模板的特化和类模板的特化
函数模板的特化
当函数模板需要对某些类型进⾏特化处理,称为函数模板的特化。
类模板的特化
当类模板内需要对某些类型进⾏特别处理时,使⽤类模板的特化。
特化整体上分为全特化和偏特化
*全特化
就是模板中模板参数全被指定为确定的类型。
全特化也就是定义了⼀个全新的类型,全特化的类中的函数可以与模板类不⼀样。
偏特化
就是模板中的模板参数没有被全部确定,需要编译器在编译时进⾏确定。
全特化的标志就是产⽣出完全确定的东西,⽽不是还需要在编译期间去搜寻适合的特化实现,貌似在我的这种理解下,全特化的东西
不论是类还是函数都有这样的特点,
1.模板函数只能全特化,没有偏特化(以后可能有)。
2.模板类是可以全特化和偏特化的。
template<>然后是完全和模板类型没有⼀点关系的类实现或者函数定义,如果你要说,都完全确定下来了,那还搞什么模板呀,直接
定义不就完事了?
但是很多时候,我们既需要⼀个模板能应对各种情形,⼜需要它对于某个特定的类型(⽐如bool)有着特别的处理,这种情形下特化
就是需要的了。
全特化的标志:template<>然后是完全和模板类型没有⼀点关系的类实现或者函数定义
偏特化的标志:template
函数模版特化
⽬前的标准中,模板函数只能全特化,没有偏特化
⾄于为什么函数不能偏特化,似乎不是因为语⾔实现不了,⽽是因为偏特化的功能可以通过函数的重载完成。
函数模版的特化技巧
函数模板的特化:当函数模板需要对某些类型进⾏特别处理,称为函数模板的特化。
例如,我们编写了⼀个泛化的⽐较程序
这个函数满⾜我们的需求了么,显然不,它⽀持常见int,float等类型的数据的⽐较,但是不⽀持char*(string)类型。
所以我们必须对其进⾏特化,以让它⽀持两个字符串的⽐较,因此我们实现了如下的特化函数。
也可以
⽰例程序1–⽐较两个数据
template
intcompare(constT&left,constT&right)
{
std::cout<<"intemplate
return(left-right);
}
template<>
intcompare
{
std::cout<<"inspecialtemplate<>..."<
returnstrcmp(left,right);
}
template<>
intcompare(constchar*left,constchar*right)
{
std::cout<<"inspecialtemplate<>..."<
returnstrcmp(left,right);
}
函数模版的特化,当函数调⽤发现有特化后的匹配函数时,会优先调⽤特化的函数,⽽不再通过函数模版来进⾏实例化。
⽰例程序⼆-判断两个数据是否相等
#include
#include
///模版特化
template
intcompare(constTleft,constTright)
{
std::cout<<"intemplate
return(left-right);
}
//这个是⼀个特化的函数模版
template<>
intcompare
{
std::cout<<"inspecialtemplate<>..."<
returnstrcmp(left,right);
}
//特化的函数模版,两个特化的模版本质相同,因此编译器会报错
//error:redefinitionof'intcompare(T,T)[withT=constchar*]'|
//template<>
//intcompare(constchar*left,constchar*right)
//{
//std::cout<<"inspecialtemplate<>..."<
//
//returnstrcmp(left,right);
//}
//这个其实本质是函数重载
intcompare(char*left,char*right)
{
std::cout<<"inoverloadfunction..."<
returnstrcmp(left,right);
}
intmain()
{
compare(1,4);
constchar*left="gatieme";
constchar*right="jeancheng";
compare(left,right);
return0;
}
类模版特化
类模板的特化:与函数模板类似,当类模板内需要对某些类型进⾏特别处理时,使⽤类模板的特化。例如:
这⾥归纳了针对⼀个模板参数的类模板特化的⼏种类型
⼀是特化为绝对类型;
⼆是特化为引⽤,指针类型;
三是特化为另外⼀个类模板。
这⾥⽤⼀个简单的例⼦来说明这三种情况:
特化为绝对类型
也就是说直接为某个特定类型做特化,这是我们最常见的⼀种特化⽅式,如特化为float,double等
#include
#include
usingnamespacestd;
//函数模板
template
boolIsEqual(Tt1,Tt2){
returnt1==t2;
}
template<>//函数模板特化
boolIsEqual(char*t1,char*t2){
returnstrcmp(t1,t2)==0;
}
intmain(intargc,char*argv[])
{
charstr1[]="abc";
charstr2[]="abc";
cout<<"函数模板和函数模板特化"<
cout<
cout<
return0;
}
如果期望使⽤偏特化,那么
#include
#include
#include
//generalversion
template
classCompare
{
public:
staticboolIsEqual(constT&lh,constT&rh)
{
std::cout<<"inthegeneralclass..."<
returnlh==rh;
}
};
//specializeforfloat
template<>
classCompare
{
public:
staticboolIsEqual(constfloat&lh,constfloat&rh)
{
std::cout<<"inthefloatspecialclass..."<
returnstd::abs(lh-rh)<10e-3;
}
};
//specializefordouble
template<>
classCompare
{
public:
staticboolIsEqual(constdouble&lh,constdouble&rh)
{
std::cout<<"inthedoublespecialclass..."<
returnstd::abs(lh-rh)<10e-6;
}
};
intmain(void)
{
Compare
std::cout<
std::cout<
Compare
std::cout<
std::cout<
Compare
std::cout<
std::cout<
return0;
}
特化为引⽤,指针类型
当然,除了T*,我们也可以将T特化为constT*,T&,constT&等,以下还是以T*为例:
这种特化其实是就不是⼀种绝对的特化,它只是对类型做了某些限定,但仍然保留了其⼀定的模板性,这种特化给我们提供了极⼤的⽅
便,如这⾥,我们就不需要对int*,float*,double*等等类型分别做特化了。
这其实是第⼆种⽅式的扩展,其实也是对类型做了某种限定,⽽不是绝对化为某个具体类型,如下:
template
classA
{
}
template
classA
{
}
template
structiterator_traits{
typedeftypename_Iterator::iterator_categoryiterator_category;
typedeftypename_Iterator::value_typevalue_type;
typedeftypename_Iterator::difference_typedifference_type;
typedeftypename_Iterator::pointerpointer;
typedeftypename_Iterator::referencereference;
};
//specializefor_Tp*
template
structiterator_traits<_Tp*>{
typedefrandom_access_iterator_tagiterator_category;
typedef_Tpvalue_type;
typedefptrdiff_tdifference_type;
typedef_Tp*pointer;
typedef_Tp&reference;
};
//specializeforconst_Tp*
template
structiterator_traits
typedefrandom_access_iterator_tagiterator_category;
typedef_Tpvalue_type;
typedefptrdiff_tdifference_type;
typedefconst_Tp*pointer;
typedefconst_Tp&reference;
};
//specializeforT*
template
classCompare
{
public:
staticboolIsEqual(constT*lh,constT*rh)
{
returnCompare
}
};
这就把IsEqual的参数限定为⼀种vector类型,但具体是vector还是vector,我们可以不关⼼,因为对于这两种类型,我们的处理⽅式是
⼀样的,我们可以把这种⽅式称为“半特化”。
当然,我们可以将其“半特化”为任何我们⾃定义的模板类类型:
这就是三种类型的模板特化,我们可以这么使⽤这个Compare类:
//specializeforvector
template
classCompare
{
public:
staticboolIsEqual(constvector
{
if(()!=())returnfal;
el
{
for(inti=0;i<();++i)
{
if(lh[i]!=rh[i])returnfal;
}
}
returntrue;
}
};
//specializeforanytemplateclasstype
template
structSpecializedType
{
T1x1;
T1x2;
};
template
classCompare
{
public:
staticboolIsEqual(constSpecializedType
{
returnCompare
}
};
//int
inti1=10;
inti2=10;
boolr1=Compare
//float
floatf1=10;
floatf2=10;
boolr2=Compare
//double
doubled1=10;
doubled2=10;
boolr3=Compare
//pointer
int*p1=&i1;
int*p2=&i2;
boolr4=Compare
//vector
vector
_back(1);
_back(2);
vector
_back(1);
_back(2);
boolr5=Compare
//customtemplateclass
SpecializedType
SpecializedType
boolr6=Compare
本文发布于:2022-11-25 16:02:29,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/19461.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |