首页 > 代码库 > traits编程技巧

traits编程技巧

template<class T>class iterator//表示迭代器针对泛型iterator_traits时的底层代码{    typedef T value_type;}; template<class Iterator>struct iterator_traits//泛化iterator_traits,作用多层间接性{    typedef typname Iterator::value_type value_type;};template<class T>struct iterator_traits<T*>//特化iterator_traits,直接提取类型{    typedef T value_type;};template<class T>struct iterator_traits<const T*>//特化iterator_traits,直接提取类型{    typedef T value_type;};//typename iterator_traits<Iterator>调用的是泛化的或者特化的template<class Iterator>typename iterator_traits<Iterator>::value_type fun(Iterator ite){    return *ite;//迭代器基本类型,以及有解引用功能}//直接使用底层型别,如果是T*,则出问题,相当于value_type被解读为T*//同样用list<int>::iterator,则被解读为list<int>::iterator,而不会深度挖掘。//显然只是适合于传递T,才能达到目的template<class Iterator>typename Iterator::value_type fun(Iterator ite){    return *ite;}fun(list<int>::iterator ite);//显然是调用了iterator_traits模板//typename iterator_traits<list<int>::iterator>::value_type//typedef typname list<int>::iterator::value_type value_type;//这就调用了list相应的迭代器中value_type,则为int。//typedef typname list<int>::iterator::int value_type;//-------------------------------------------------------------上述是T类型,榨取---------------------------//stl-iterator头文件//具体的模板,可能需要的具体的5种型别不一样,有的模板直接可以确定下来。所以定义一个最高的母版为下template <class Category, class T, class Distance = ptrdiff_t,          class Pointer = T*, class Reference = T&>struct iterator {  typedef Category  iterator_category;  typedef T         value_type;  typedef Distance  difference_type;  typedef Pointer   pointer;  typedef Reference reference;};//例如<假象的>vector特化迭代器template<class T>struct vector_iterator:public iterator<random_access_iterator_tag,T>{  typedef random_access_iterator_tag  iterator_category;//vector模板可以确定  typedef T         value_type;  typedef size_type  difference_type;//可以确定下来了  typedef Pointer   pointer;  typedef Reference reference;};//基础榨取机模板类----泛化template<class I>struct iterator_traits{    typedef I::value_type value_type;//迭代器所指的类型    typedef I::difference_type difference_type;//迭代器距离    typedef I::pointer pointer;    typedef I::reference reference;    typedef I::iteratro_category iterator_category;//迭代器类型。};//特化版1template<class T>struct iterator_traits<T*>{    typedef T value_type;//迭代器所指的类型    typedef ptrdiff_t difference_type;//迭代器距离    typedef T* pointer;    typedef T& reference;    typedef random_access_iterator_tag iterator_category;    };//特化版2template<class T>struct iterator_traits<const T*>{    typedef T value_type;//迭代器所指的类型    typedef ptrdiff_t difference_type;//迭代器距离    typedef T* pointer;    typedef T& reference;    typedef random_access_iterator_tag iterator_category;};//应用部分template<class I>typename iterator_traits<I>::difference_type f(I);//榨取其中的ptrdiff_t//如果I传入的是类型为list<vector<int>>则,会先看list迭代器,取出其中元素为vector<int>,细调用//vector的difference_type,此时就会调用int的difference_type,那此处就会有difference_type的类别名template<class I>typename iterator_traits<I>::value_type f();//榨取其中的Ttemplate<class I>typename iterator_traits<I>::pointer f();//榨取其中的T*template<class I>typename iterator_traits<I>::reference f();//榨取其中的T&template<class I>typename iterator_traits<I>::iterator_category f();//榨取其中的random_access_iterator_tag//------------------------------下述,产生iterator_category的型别因素---------------------------------//将5种类型迭代器,构造一个空类,其这样做目的是区分种类类型,而不需要任何数据成员。struct input_iterator_tag {};struct output_iterator_tag {};struct forward_iterator_tag : public input_iterator_tag {};struct bidirectional_iterator_tag : public forward_iterator_tag {};struct random_access_iterator_tag : public bidirectional_iterator_tag {};//输入迭代器---只读,单向template <class InputIterator, class Distance>inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {  while (n--) ++i;}//双向迭代器---可读写,双向template <class BidirectionalIterator, class Distance>inline void __advance(BidirectionalIterator& i, Distance n,                       bidirectional_iterator_tag) {  if (n >= 0)    while (n--) ++i;  else    while (n++) --i;}//随机迭代器---可读写,随机访问template <class RandomAccessIterator, class Distance>inline void __advance(RandomAccessIterator& i, Distance n,                       random_access_iterator_tag) {  i += n;}//外口函数--客户端使用的,是2个参数的advance函数,是根据传入时的迭代器类型不同而定下采用哪个函数template <class InputIterator, class Distance>inline void advance(InputIterator& i, Distance n) {  __advance(i, n, iterator_category(i));}//获取迭代器的 距离。----放回距离的指针,其值为0template <class Iterator>inline typename iterator_traits<Iterator>::difference_type*distance_type(const Iterator&) {  return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);}//获取迭代器所指元素类型---放回元素类型指针,其值为0template <class Iterator>inline typename iterator_traits<Iterator>::value_type*value_type(const Iterator&) {  return static_cast<typename iterator_traits<Iterator>::value_type*>(0);}//函数获取,迭代器种类型别,放回种类型别对象,初始化后的template <class Iterator>inline typename iterator_traits<Iterator>::iterator_categoryiterator_category(const Iterator&) {  typedef typename iterator_traits<Iterator>::iterator_category category;//此处出来的最后是某个_tag类型  return category();}//例如:advance(vector<int>::iterator,2);//通过传入的vector迭代器,则可以通过榨取机获得此类型为随机访问迭代器模型//因为它会调用vector模板中的iterator_category,而它则某个_bag,则显然会被定义为随机访问迭代器。而不会是//迭代器的I::iterator_category,故而和vector<list<int>>的迭代器类型应该是一致的。//---------------------------------------------------//

traits编程技巧