|
一、类模板的深入学习: 1、类模板可以定义任意多个不同的类型参数(这一点和模板函数一样) template < typename T1, typenaem T2 >! ~+ t* _( z) Q3 ^% `$ p8 z/ M, ~class Test { public: void add(T1 a, T2 b); } //定义类对象时 Test<int,float> t;" |; p k& L' H$ x, G7 [9 i( y 2、类模板可以被特化
特化前: template < typename T1, typename T2 >class Test {8 s) z$ `" x0 c' E }; 特化后: template < typename T >! L- W$ }3 v; e3 @0 [class Test < T , T > {1 y- T \4 b5 q' m$ `. U @1 G+ Z' n2 c }; 3、类模板的特化类型:
完全特化前: template <typename T1, typename T2 > O/ v, Q! |2 t! C' jclass Test {+ k% t3 r0 c( o% `. z' Z ) Y! H {, |* u7 c% S };' S$ G+ t: p3 y, J: T. _9 l 完全特化后: template < >4 R7 g4 U: r, z/ W E" U1 s$ T! s2 Qclass Test < int, int> { # ]* x5 }" Y) i' q/ P# R( h }; 代码实践: #include <iostream>3 P, _' d) U5 L! t9 _$ K3 D#include <string> 6 z+ I$ S2 b. m# _' C using namespace std; template < typename T1, typename T2 >- D8 f% Z5 ~. {1 q& f/ h class Test { public: void add(T1 a, T2 b)$ p- x! e( N* E( `) Y0 m5 f& d { cout<<"void add(T1 a, T2 b)"<<endl; cout<<a+b<<endl; } };7 t) T! B, {, S& V5 {' @ * h9 J4 c* o" u0 _ /* 关于上述第一个类模板的特殊实现,关于指针的特化实现 */ template < typename T1 , typename T2 >- |! }* p3 t- i/ P- ` class Test < T1*, T2* > { public: void add(T1* a, T2* b)) x" p3 ^: O' h u8 ]/ ?8 T) Q* g' E {% H: P' u i5 {% E cout<<"void add(T1* a, T2* b)"<<endl;0 L8 L4 P: ]1 c/ S0 F) I [$ o cout<<*a+*b<<endl;. y+ R' j2 H* Q! ^" M5 | } }; % @9 @1 L/ m3 {& z" _. M template < typename T >//特化' u( P' [$ H4 u class Test <T ,T ># ~+ j" R4 h6 C { public: void add(T a, T b)! W3 A/ \0 U: Q# k5 }( x { cout<<"void add(T a, T b)"<<endl; cout<<a+b<<endl;/ s7 i$ V0 l) A, `( v1 d/ C9 P }9 ~+ W) J) y8 v3 L4 a2 s void print() { 0 g$ }) v. O4 v" ?8 p cout<<"class Test < T , T >"<<endl;& R" Y% h6 r- O }2 e- N3 D# q' f4 V; i }; template < >//完全特化9 C6 t, V+ R+ J class Test < void * , void * > {. c% r# i/ g" X1 V6 h" w+ ?% V: { public:( J# ^4 {+ c, {4 g1 I" J void add(void* a, void* b); ?- e1 u7 {/ h! S { cout<<"void add(void* a, void* b)"<<endl;( F, ^; n5 |& h' {5 h2 P cout<<"error to add void* parm"<<endl; }( `( G7 E& B8 u, e4 u# N6 W };* q/ n9 b7 S9 Z: g# X / s$ e' n) d' _. Y% n int main(), z0 i) v( p8 q0 b- c% e { Test<int, float> t1;5 U/ y0 {7 N, X6 N) N2 ~ Test<long, long> t2; Test<void*, void*> t3;. ?) f. s8 B* `; A- W2 G' n, t " V [- L! o2 |! Y2 b$ N t1.add(1,2.5);; B; D! o: E& B6 \7 E# B1 ^" m6 A t2.add(5,5); t2.print(); t3.add(NULL,NULL); Test< int* , double* > t4; int a =1; double b = 0.1; t4.add(&a,&b);) e7 }1 Q: O$ `2 G3 S/ j3 E return 0;7 j& d/ C. G2 X- O; H; q6 i; D' { }$ G7 T1 L# J# O; t& ~ 输出结果: root@txp-virtual-machine:/home/txp# ./a.outvoid add(T1 a, T2 b) 3.5+ o$ ~% L- _9 o5 l- ` void add(T a, T b) 100 z/ e) I4 l4 c% F2 ~ class Test < T , T > void add(void* a, void* b) error to add void* parm- }$ p% N- ^( _. p4 y( h7 j1 \9 P void add(T1* a, T2* b) 1.19 _! B5 o( t. j* [. T5 m 4、类模板特化注意事项: (1)特化只是模板的分开实现 本质上是同一个类模板 (2)特化类模板的使用方式是统一的 必须显示指定每一个类型参数 5、类模板特化与重定义有区别吗?函数模板可以特化吗? (1)重定义和特化的不同: 重定义: --一个类模板和一个新类(或者两个类模板) --使用的时候需要考虑如何选择的问题 特化: --以统一的方式类使用类模板的特化类 --编译器自动优先选择特化类 (2)函数模板只支持参数完全特化 函数模板特化前: template < typename T >: G0 R0 P% N4 x6 H bool Equal(T a, T b) {+ h! Q4 v/ ~1 }' r, c M" U return a==b; }# ~8 h9 a2 K' t0 O8 X$ ] 函数模板完全特化后: template < >* { `( S, F2 q! w2 Zbool Euqal<void*>(void* a, void* b)& m: {9 n5 ^ ^ { return a==b; } 代码实践: #include <iostream>#include <string> + } V* _8 X0 J, H using namespace std; template7 K) a% \/ f+ y1 l+ `7 Q3 _ < typename T1, typename T2 >9 V% _2 q8 ~# J" q# d, z class Test { public:$ v" ]' c/ n0 i: e- K* S V void add(T1 a, T2 b)7 O1 a* C) j5 \1 a9 S8 M { cout << "void add(T1 a, T2 b)" << endl; cout << a + b << endl; }+ b5 S5 K1 y3 [ }; /* template% T* o* z, E% X9 O( {& R+ f < >. N# X ~+ Q+ m# e0 K& f2 V- r) N class Test < void*, void* > // 当 T1 == void* 并且 T2 == void* 时 { public: void add(void* a, void* b)8 a7 V& _4 p# u& ^8 Y3 W {, k f4 ?3 G- \8 }2 u# Z cout << "void add(void* a, void* b)" << endl;- C2 E" P) {' d) G cout << "Error to add void* param..." << endl;: ^8 t+ v( b$ ]1 ]9 p7 b# Z* H } }; */1 b5 R! d1 M, w; a2 P1 _ . N/ i2 Y1 f7 i0 C class Test_Void. R% P9 @# A, {( ?2 a; ?+ F {7 X$ B/ U0 |5 P! Y1 a8 I5 O" h5 P: @ public: void add(void* a, void* b) {! u% O: r, K& K( n# A/ J cout << "void add(void* a, void* b)" << endl;) ~( o; T1 b/ p: J cout << "Error to add void* param..." << endl;4 D! |& ~! R& t. Y } };' z; W; B* W, g7 F P0 i* U& L! ` H) Q5 u template < typename T > bool Equal(T a, T b)' x" p/ ]9 l! s7 [6 T { cout << "bool Equal(T a, T b)" << endl;! R: ^/ A1 L# j- P- K1 f7 T! w0 } " m6 G5 `0 _: L4 e return a == b; } template! g1 W. S* i4 u < >" h7 x, G, V6 R# y6 D' G bool Equal<double>(double a, double b)+ F; H& W7 p; S0 b, M { const double delta = 0.00000000000001;0 [6 ]: \, c$ i( V4 c8 C4 w6 n0 z0 r double r = a - b;8 n w7 ^3 [8 x4 N cout << "bool Equal<double>(double a, double b)" << endl; 9 a# l0 A1 ~5 h3 R* S5 p7 F- r return (-delta < r) && (r < delta);: D+ s7 o" L! N8 w }' t5 U. C/ A" p* R E9 m" W% S0 v6 _ bool Equal(double a, double b) { const double delta = 0.00000000000001; double r = a - b; cout << "bool Equal(double a, double b)" << endl;# e$ d) N9 ?/ `; B0 J" M; k return (-delta < r) && (r < delta); } C d l9 y& z- r9 w9 w3 @/ O int main() { cout << Equal( 1, 1 ) << endl; cout << Equal<>( 0.001, 0.001 ) << endl; 0 E; X, a/ Q4 f# [: d* U5 x return 0; } - G' t9 s/ X* d# @9 t: V 输出结果: root@txp-virtual-machine:/home/txp# ./a.outbool Equal(T a, T b) 1 bool Equal<double>(double a, double b) 1 . L3 t' d# q7 E$ H, a$ s 注解:当需要重载函数模板时,优先考虑使用模板特化;当模板特化无法满足需求,再使用函数重载 二、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版