specialize

更新时间:2022-11-25 16:02:29 阅读: 评论:0


2022年11月25日发(作者:暑假补习班)

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(constchar*left,constchar*right)

{

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(constchar*left,constchar*right)

{

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)

{

Comparecomp1;

std::cout<

std::cout<

Comparecomp2;

std::cout<

std::cout<

Comparecomp3;

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(*lh,*rh);

}

};

这就把IsEqual的参数限定为⼀种vector类型,但具体是vector还是vector,我们可以不关⼼,因为对于这两种类型,我们的处理⽅式是

⼀样的,我们可以把这种⽅式称为“半特化”。

当然,我们可以将其“半特化”为任何我们⾃定义的模板类类型:

这就是三种类型的模板特化,我们可以这么使⽤这个Compare类:

//specializeforvector

template

classCompare>

{

public:

staticboolIsEqual(constvector&lh,constvector&rh)

{

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&lh,constSpecializedType&rh)

{

returnCompare::IsEqual(lh.x1+lh.x2,rh.x1+rh.x2);

}

};

//int

inti1=10;

inti2=10;

boolr1=Compare::IsEqual(i1,i2);

//float

floatf1=10;

floatf2=10;

boolr2=Compare::IsEqual(f1,f2);

//double

doubled1=10;

doubled2=10;

boolr3=Compare::IsEqual(d1,d2);

//pointer

int*p1=&i1;

int*p2=&i2;

boolr4=Compare::IsEqual(p1,p2);

//vector

vectorv1;

_back(1);

_back(2);

vectorv2;

_back(1);

_back(2);

boolr5=Compare>::IsEqual(v1,v2);

//customtemplateclass

SpecializedTypes1={10.1f,10.2f};

SpecializedTypes2={10.3f,10.0f};

boolr6=Compare>::IsEqual(s1,s2);

本文发布于:2022-11-25 16:02:29,感谢您对本站的认可!

本文链接:http://www.wtabcd.cn/fanwen/fan/90/19461.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

上一篇:drank
下一篇:长颈鹿美语
标签:specialize
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图