模板特化和偏特化

模板特化和偏特化 谢宝陵 周 生 摘要:本文通过例子介绍了在 C++标准库中广泛使用的模板特化和偏特化,并指出了模板特化和偏特化的定义规则和应用规则。 关键词:模板、特化、偏特化 1.引言 C++中的模板分为类模板和函数模板,虽然它引进到C++标准中的时间不是很长,但是却得到了广泛的应用,这一点在STL中有着充分的体现。目前,STL在C++社区中得到了广泛的关注、应用和研究。理解和掌握模板是学习、应用和研究以及扩充STL的基础。而STL模板实例中又充斥着大量的模板特化和偏特化。 2.模板的定义 (1) 类模板 定义一个栈的类模板,它可以用来容纳不同的数据类型 说明如下: template class stack { private: list* top; public: stack(); stack(const stack&); ~stack(); void push(T&); T& pop(); //… }; 上述定义中,template告诉编译器这是一个模板,尖括号中的 指明模板的参数,可以有一个或多个,具体实现时由用户指定,其中template 中的关键字class可以用关键字typename来代替。 类模板的使用除了要在声明时指明模板参数外,其余均与普通的类相同,例如: stack int_stack; stack ch_stack; stack str_stack; int_stack.push(10); ch_stack.push(‘z’); str_stack.push(“c++”); (2) 函数模板 假设现在要定义一个max函数来返回同一类型(这种类型是允许比较的)两个值的最大者. template T mymax(const T& t1,const T& t2) { return t1 < t2 ? t2 : t1; } template 的意义与类模板定义中相同。 模板函数的使用与普通非模板函数使用相同,因为模板函数的参数可以从其传入参数中解析出来。例如: int highest = mymax(5,10); char c = mymax(‘a’, ’z’); mymax(5,10)解析出模板函数参数为int, mymax(‘a’, ’z’)解析出模板函数的参数为char。 3.模板的特化 (1) 类模板特化 有时为了需要,针对特定的类型,需要对模板进行特化,也就是特殊处理.例如,stack类模板针对bool类型,因为实际上bool类型只需要一个二进制位,就可以对其进行存储,使用一个字或者一个字节都是浪费存储空间的. template class stack {}; template < > class stack { //…// }; 上述定义中template < >告诉编译器这是一个特化的模板。 (2) 函数模板的特化 看下面的例子 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); } 前面两个mymax都能返回正确的结果.而第三个却不能,因为,此时mymax直接比较两个指针p1 和 p2 而不是其指向的内容. 针对这种情况,当mymax函数的参数类型为const char* 时,需要特化。 template T mymax(const T t1, const T t2) { return t1 < t2 ? t2 : t1; } template <> const char* mymax(const char* t1,const char* t2) { return (strcmp(t1,t2) < 0) ? t2 : t1; } 现在mymax(p1,p2)能够返回正确的结果了。 4.模板的偏特化 模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化 (1) 类模板的偏特化 例如c++标准库中的类vector的定义 template class vector { // … // }; template class vector { //…//}; 这个偏特化的例子中,一个参数被绑定到bool类型,而另一个参数仍未绑定需要由用户指定。 (2) 函数模板的偏特化 严格的来说,函数模板并不支持偏特化,但由于可以对函数进行重载,所以可以达到类似于类模板偏特化的效果。 template void f(T); (a) 根据重载规则,对(a)进行重载 template < class T> void f(T*); (b) 如果将(a)称为基模板,那么(b)称为对基模板(a)的重载,而非对(a)的偏特化。C++的标准委员会仍在对下一个版本中是否允许函数模板的偏特化进行讨论。 5.模板特化时的匹配规则 (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); // 调用(g) 参考文献 [1] Bjarne Stroustrup, The C++ Programming Language (Special Edition), Addison Wesley,2000 [2] Nicolai M.Josuttis, The C++ Standard Library – A Tutorial and Reference ,Addison Wesley,1999 [3] Stanley Lippman and Josée Lajoie ,C++ Primier, 3rd Edition ,Addison Wesley Longman ,1998
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值