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;//迭代器類型。
};
//特化版1
template<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;
    
};
//特化版2
template<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();//榨取其中的T
template<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));
}
//獲取迭代器的 距離。----放回距離的指針,其值爲0
template <class Iterator>
inline typename iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&) {
  return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);
}
//獲取迭代器所指元素類型---放回元素類型指針,其值爲0
template <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_category
iterator_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>>的迭代器類型應該是一致的。
//---------------------------------------------------//
相關文章
相關標籤/搜索