C + + class template Three kinds of special, speak more comprehensive
by Smartptr (http://www.cppblog.com/SmartPtr/)
There are several types of class template specificity for a template parameter, one is special to absolute type (full specificity), the other is special to reference, pointer type (semi-special, partial), and three is special to another class template (complex point of the partial special).
Use a simple example to illustrate these three types:
// General versiontemplate<class t>class compare{public: staticbool isequal (constconst t& RH) { return LH = = RH; }};
This is a class template for comparison, which can have a variety of functions for comparison, taking IsEqual as an example.
First, special to absolute type
That is, directly to a particular type of special, this is our most common kind of special way, such as special to float, double, etc.
//specialize for floatTemplate<>classcompare<float>{ Public: Static BOOLIsEqual (Const float& LH,Const float&RH) { returnABS (LH-RH) < 10e-3; }};//specialize for doubleTemplate<>classcompare<Double>{ Public: Static BOOLIsEqual (Const Double& LH,Const Double&RH) { returnABS (LH-RH) < 10e-6; }};
Second, special to reference, pointer type
This kind of special I was originally found in the STL source Iterator_traits, as follows:
Template <class_iterator>structiterator_traits {typedef typename _iterator::iterator_category iterator_category; typedef typename _ITERATOR::VALUE_TYPE Value_type; typedef typename _iterator::d ifference_type difference_type; typedef typename _iterator::p ointer 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; typedefConst_tp*pointer; typedefConst_tp&reference;};
Of course, in addition to t*, we can also convert T to const t*, T&, const t&, and so on, the following is t* for example:
// specialize for t*template<class t>class compare<t*>{public : staticbool isequal (constconst t* RH) { return Compare<t>::isequal (*LH, *RH); };
This special is not an absolute special, it is only the type of certain limitations, but still retains its certain template, this special to provide us with great convenience, such as here, we do not need to int*, float*, double* and so on the types of special.
Third, special to another class template
This is actually the second way of extension, in fact, the type has been a certain qualification, rather than absolute to a specific type, as follows:
//specialize for vector<t>template<classT>classcompare<vector<t> >{ Public: Static BOOLIsEqual (Constvector<t>& LH,Constvector<t>&RH) { if(Lh.size ()! = Rh.size ())return false; Else { for(inti =0; I < lh.size (); ++i) {if(Lh[i]! = Rh[i])return false; } } return true; }};
This limits the isequal parameter to a type of vector, but specifically vector<int> or vector<float> we don't care, because for both types, we're dealing with the same way, We can refer to this approach as "semi-specific".
Of course, we can make it "semi-specific" for any of our custom template class types:
//specialize for any template class typeTemplate <classT1>structspecializedtype{T1 x1; T1 x2;}; Template<classT>classcompare<specializedtype<t> >{ Public: Static BOOLIsEqual (Constspecializedtype<t>& LH,Constspecializedtype<t>&RH) { returnCompare<t>::isequal (lh.x1 + lh.x2, rh.x1 +rh.x2); }};
This is the three types of template specificity that we can use in this compare class:
//int intI1 =Ten; intI2 =Ten; BOOLR1 = compare<int>:: IsEqual (I1, I2); //float floatF1 =Ten; floatF2 =Ten; BOOLr2 = compare<float>:: IsEqual (f1, F2); //Double DoubleD1 =Ten; DoubleD2 =Ten; BOOLR3 = compare<Double>:: IsEqual (D1, D2); //Pointer int* P1 = &I1; int* P2 = &I2; BOOLR4 = compare<int*>:: IsEqual (P1, p2); //vector<t>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 classspecializedtype<float> S1 = {10.1f,10.2f}; Specializedtype<float> s2 = {10.3f,10.0f}; BOOLR6 = compare<specializedtype<float> >::isequal (S1, S2);
the specificity of C + + function templates
function template is special, function template only fully special, no semi-special
Look at the following example
Main () { int highest = Mymax (5,ten); char c = Mymax (' A ', ' Z '); Const char* p1 = "Hello"; Const char* p2 = "World"; Const char* p = Mymax (P1,P2);}
The first two Mymax can return the correct result. But the third cannot, because, at this time Mymax directly compares two pointers P1 and p2 instead of what they point to.
In this case, when the parameter type of the Mymax function is const char*, it needs to be special.
Template <class t>t Mymax (constconst t t2) { return T1 < T2? <>constChar* MYMAX (constChar* T1,const Char* T2) { return0)? t2:t1;}
Now Mymax (P1,P2) can return the correct results.
The partial specificity of function template
Strictly speaking, function templates do not support biasing, but because functions can be overloaded, it is possible to achieve a similar effect to class template biasing.
Template <class t> void f (T); (a)
Overloading of (a) based on overloading rules
template < class t> void F (t*); (b)
if (a) is called a base template, then (b) is called an overload of the base template (a) rather than a bias to (a).
The standard Committee for C + + is still discussing whether to allow the partial localization of function templates in the next release.
The specificity of C + + templates