C++模板特化(ZZ)

c++模板特化

一、模板特化, specialization of template

模板特化(specialization of template)并不是说实例化一个模板,如template ,class stack;声明stack,这是实例化一个模板类。

类模板特化的意思是,对于某个特定的类型,需要对模板进行特殊化,即特殊的处理。例如,stack类模板针对bool类型有特化,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的.

同样,函数模板特化也是针对某个特定类型的特殊处理,一个比较经典的例子:

template

T mymax(const T t1, const T t2)

{

return t1 < t2 ? t2 : t1;

}

main()

{

int highest = mymax(5,10);//正确结果

char c = mymax(‘a’, ’z’);//正确结果

const char p1 = “hello”;

const char
p2 = “world”;

const char p = mymax(p1,p2);//错误结果,因为比较的是指针,而不是内容

}



如果需要得到正确结果就需要针对const char
的函数模板特化:

const char mymax(const char t1,const char t2)

{

return (strcmp(t1,t2) < 0) ? t2 : t1;

}



二、模板偏特化,partial specialization of template

模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化。

1. 类模板的偏特化

例如c++标准库中的类vector的定义

template

class vector { // … // };

template

class vector { //…//};

这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。



2. 函数模板偏特化

严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。

template void f(T); (a)

根据重载规则,对(a)进行重载

template void f(T
); (b)

如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。

三、模板特化时的匹配规则

(1) 类模板的匹配规则

最优化的优于次特化的,即模板参数最精确匹配的具有最高的优先权

例子:

template class vector{//…//}; // (a) 普通型

template class vector{//…//}; // (b) 对指针类型特化

template <> class vector {//…//}; // (c) 对void进行特化

每个类型都可以用作普通型(a)的参数,但只有指针类型才能用作(b)的参数,而只有void
才能作为(c)的参数

(2) 函数模板的匹配规则

非模板函数具有最高的优先权。如果不存在匹配的非模板函数的话,那么最匹配的和最特化的函数具有高优先权

例子:

template void f(T); // (d)

template void f(int, T, double); // (e)

template void f(T); // (f)

template <> void f (int) ; // (g)

void f(double); // (h)

bool b;

int i;

double d;

f(b); // 以 T = bool 调用 (d)

f(i,42,d) // 以 T = int 调用(e)

f(&i) ; // 以 T = int
调用(f)

f(d); // 调用(h)



[附]

区别

前者只支持窄字符集,已经被ANSI/ISO C++标准委员会舍弃

后者支持窄字符集和宽字符集

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jinjinClouded/archive/2010/01/26/5256925.aspx

一、特化为绝对类型

也就是说直接为某个特定类型做特化,这是我们最常见的一种特化方式, 如特化为float, double等
//specialize for float

template<>

classCompare<float>

{

public:

staticboolIsEqual(constfloat&lh,constfloat&
rh)

{

returnabs(lh-rh)<10e-3
;

}

};



//specialize for double


template<>

classCompare<double>

{

public:

staticboolIsEqual(constdouble&lh,constdouble&
rh)

{

returnabs(lh-rh)<10e-6
;

}

};






二、特化为引用,指针类型

这种特化我最初是在stl源码的的iterator_traits特化中发现的, 如下:

template<class_Iterator>

structiterator_traits {

typedef typename _Iterator::iterator_category iterator_category;

typedef typename _Iterator::value_type value_type;

typedef typename _Iterator::difference_type difference_type;

typedef typename _Iterator::pointer pointer;

typedef typename _Iterator::reference reference;

};



//specialize for _Tp


template<class_Tp>

structiterator_traits<_Tp
>{

typedef random_access_iterator_tag iterator_category;

typedef _Tp value_type;

typedef ptrdiff_t difference_type;

typedef _Tp
pointer;

typedef _Tp
&
reference;

};



//specialize for const _Tp


template<class_Tp>

structiterator_traits<const_Tp>{

typedef random_access_iterator_tag iterator_category;

typedef _Tp value_type;

typedef ptrdiff_t difference_type;

typedef
const_Tp
pointer;

typedef
const_Tp&
reference;

};



当然,除了T, 我们也可以将T特化为 const T, T&, const T&等,以下还是以T*为例:

//specialize for T

template<classT>

classCompare<T
>

{

public:

staticboolIsEqual(constTlh,constT
rh)

{

returnCompare<T>::IsEqual(lh,
rh);

}

};

这种特化其实是就不是一种绝对的特化, 它只是对类型做了某些限定,但仍然保留了其一定的模板性,这种特化给我们提供了极大的方便, 如这里, 我们就不需要对int, float, double*等等类型分别做特化了。

三、特化为另外一个类模板

这其实是第二种方式的扩展,其实也是对类型做了某种限定,而不是绝对化为某个具体类型,如下:

//specialize for vector

template<classT>

classCompare<vector<T>>

{

public:

staticboolIsEqual(constvector<T>&lh,constvector<T>&
rh)

{

if(lh.size()!=rh.size())returnfalse
;

else


{

for(inti=0; i<lh.size();++i)

{

if(lh[i]!=rh[i])returnfalse
;

}

}

returntrue
;

}

};


这就把IsEqual的参数限定为一种vector类型, 但具体是vector还是vector, 我们可以不关心, 因为对于这两种类型,我们的处理方式是一样的,我们可以把这种方式称为“半特化”。

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

//specialize for any template class type

template<classT1>

struct
SpecializedType

{

T1 x1;

T1 x2;

};

template
<classT>


classCompare<SpecializedType<T>>

{

public:

staticboolIsEqual(constSpecializedType<T>&lh,constSpecializedType<T>&
rh)

{

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

}

};


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

//int

inti1=10;

inti2=10
;

boolr1=Compare<int>
::IsEqual(i1, i2);



//float


floatf1=10;

floatf2=10
;

boolr2=Compare<float>
::IsEqual(f1, f2);



//double


doubled1=10;

doubled2=10
;

boolr3=Compare<double>
::IsEqual(d1, d2);



//pointer


intp1=&i1;

int
p2=&i2;

boolr4=Compare<int*>
::IsEqual(p1, p2);



//vector


vector<int>v1;

v1.push_back(
1
);

v1.push_back(
2
);



vector
<int>
v2;

v2.push_back(
1
);

v2.push_back(
2
);

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



//custom template class


SpecializedType<float>s1={10.1f,10.2f};

SpecializedType
<float>s2={10.3f,10.0f
};

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

原文链接: https://www.cnblogs.com/gin_dl/archive/2010/04/05/1704856.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/9564

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月6日 下午10:25
下一篇 2023年2月6日 下午10:25

相关推荐