In STL's algorithms, our hope is often to perform different, more efficient operations based on different types of iterators:
1Template<typename Itert, TypeName distt>2 voidAdvance (itert iter, Distt dis)3 {4 if(ITER isa random access iterator)5ITER + =dis;6 Else{7 if(Dis >=0){8 while(dis--)9iter++;Ten}Else{ One while(dis++) Aiter--; - } - } the};
This technique of identifying the iterator category is called Iterator_traits, and the first requirement for each user-defined iterator type should be a TypeDef, similar to the following:
1 template<...>2class list{3public:4 class iterator{5 typedef typename BIDIRECTIONAL_ITERATOR_TAG Iterator_category; 6 ... 7 }; 8 };
This allows the iterator_traits to extract the type of the iterator through the extraction technique:
1 template<typename itert>2struct iterator_traits3{ 4 typedef typename Itert::iterator_category iterator_category; 5 ... 6 };
The above technique may not work for pointers carcass, because pointers cannot be built to specify iteartor_catagory; This problem can only be solved by the specificity of the template:
1 tempalte<typename itert>2struct iterator_traits<itert *>3{ 4 typedef random_access_iterator_tag iterator_category; 5 ... 6 };
With Iterator_traits technology, it is possible to achieve an efficient iteration. But it is not actually implemented through the form of if Iterator is a random_access_iterator, but by overloading the function:
1Template<typename Itert, TypeName distt>2Doadvance (Itert iter, Distt D, Std::random_access_iterator_tag)//the tag here is often first extracted by iterator_traits;3 {4ITER + =D;5 }6Template<typename Itert, TypeName distt>7 doadvance (Itert iter, Distt D, Std::bidirectional_iterator_tag)8 {9 if(Dis >=0){Ten while(dis--) Oneiter++; A}Else - while(dis++) -iter--; the } -Tempalte<typename Itert, TypeName distt> -Doadvance (Itert iter, Distt D, Std::input_iterator_tag)//note the iterator version here - { + if(D <0) - ThrowStd::out_of_range ("negetive distance!"); + Else{ A while(d--) + +iter; at } -}The last version of Doadvanced is actually a input_iterator version, but since Forward_iterator_tag is inherited from Input_iterator_tag, So the doadvance here can also handle the forward iterator. By the different versions above, iterator can actually write the implementation version of the advance:
1 template<typename Itert, TypeName distt>2doadvance (Itert iter, Distt D)3 {4 5 // Note that the TypeName6 } is used here
So, a traits class is actually equivalent to:Create a set of H-overloaded functions or function templates that differ only in their traits parameters. Create a control function or template function to invoke the above template function and pass the traits information.
Summary:Trait_class makes the information about the type available at compile time, which is done with the exception of template and template. combined with the overloaded mechanism, Traits_class may be able to perform if-else tests on the type at compile time.
Article 47: Please use traits class to represent type information