Traits in C + + is commonly used in STL to extract type information.
For example, define a function template with a template parameter of type T, and return a value of type T.
Template <class t>typename t::value_type f (T iter) {return *iter;}
The return value type of this function is T::value type, so that the type of T is vector,list,deque and so on, it can be processed. However, with one exception, when T is a normal pointer type, the normal pointer does not have a value_type type. The solution to this problem is to use the Taits feature.
Define the traits class as follows:
Template <class t>struct Iteratortraits{typedef typename T::value_type value_type;}; Template <class t>typename iteratortraits<t>::value_typef (T iter) {return *iter;}
In this way, the type information can be extracted through the Iteratortraits class, but this does not solve the problem of ordinary pointers, this function f generalization is not good enough to solve this problem as long as the definition of iteratortraits version of the partial specialization.
Template <class t>struct iteratortraits<t *>{typedef T value_type;};
So the whole program is:
# include <iostream># include <vector>using namespace std;template <class t>struct iteratortraits{ typedef typename T::value_type Value_type;}; Template <class t>struct iteratortraits<t *>{typedef T value_type;}; Template <class t>typename iteratortraits<t>::value_typef (T iter) {return *iter;} int main () {int a[5]={1,2,3,4,5};vector <int> V (a,a+5); Vector<int>::iterator iter=v.begin (); int B=5;int *p =&b;cout<<f (ITER) <<endl;cout<<f (p) <<endl; Call the biased version of system ("pause"); return 0;}
Here is an application of the traits feature:
The program is implemented by the advance function, that is, to move an iterator to the D position, for different iterators, in order to improve the efficiency of the operation, the method of movement is different. For example, for random access iterators, just iter+=d, and for bidirectional iterators, this moves step-by-step, similar to the form of while (d--) iter++. Use the traits attribute to extract the type of the iterator and then invoke a different overloaded version, which is the way to solve the problem.
# include <iostream># include <vector># include <list>using namespace Std;template <typename Itert, TypeName Distt>void advancehelp (Itert &iter,distt d,std::random_access_iterator_tag) {iter+=d; Random Access iterator}template <typename itert,typename distt>void advancehelp (Itert &iter,distt D,std::bidirectional_ Iterator_tag) {if (d>=0)//bidirectional iterator {while (d--) ++iter;} else {while (d++)--iter;}} Template <typename itert,typename distt>void advanceiter (itert &iter,distt D) {//iterator type as parameter passed in function Advancehelp ( Iter,d,typename std::iterator_traits<itert>::iterator_category ());} int main () {int a[7]={1,2,3,4,5,6,7};vector <int> V (a,a+7); Vector<int>::iterator Iter=v.begin (); Advanceiter (iter,3);//Call Random_access_iterator_tag version cout<<*iter<<endl;list<int> Li (a,a+7); List<int>::iterator Iter1=li.begin (); Advanceiter (iter1,4); Call Bidirectional_iterator_tag version cout<<*iter1<<endl;advanceiter (iter1,-4); Call Bidirectional_iteratoR_tag version Cout<<*iter1<<endl;system ("pause"); return 0;}