c++ traits技法理解

終於理解了c++ traits技法,不得不說它對c++的作用可以說是很大,讓編程效率可以提升很多,爲什麼這多說,就是當我們在寫了一個模板後,traits技法可以讓這個模板的通用性更強,模板偏特化就會在模板泛化中再設計一個特別的版本,看下面這個列子,對於模板參數是一個一個普通類型時,它會匹配第一個模板,當爲指針時匹配第二個模板,這就區分開了兩種,可以有不同的處理方式

template<typename T>
struct A {
    
};

template<typename T>    //偏特化版本
struct A<T*> {
    
};

再看下面例子, 是traits在迭代器裏簡單應用的抽象例子,我們就可以根據模板裏的參數類型來賦值,使其能調用相應的函數

template<class IterT>
struct my_iterator_traits {
    typedef typename IterT::value_type value_type;
};

template<class IterT>
struct my_iterator_traits<IterT*> {
    typedef IterT value_type;
};

void fun(int a) {
    cout << "fun(int) is called" << endl;
}

void fun(double a) {
    cout << "fun(double) is called" << endl;
}

void fun(char a) {
    cout << "fun(char) is called" << endl;
}

int main()
{
    my_iterator_traits<vector<int>::iterator>::value_type p;    //vector迭代器內部有一個typedef T value_type;有迭代器的value_type就可知類型
    fun(p);
    my_iterator_traits<int*>::value_type q;
    fun(q);
}

 來看一看iterator_traits的源碼,對於iterator_traits類,通過調用它的iterator_category獲得它的參數類型,即相應的迭代器類型,這樣一來,我們就可以獲取到任何類型的相應型別


template <class Iterator>
struct iterator_traits {
  typedef typename Iterator::iterator_category iterator_category;
  typedef typename Iterator::value_type        value_type;
  typedef typename Iterator::difference_type   difference_type;
  typedef typename Iterator::pointer           pointer;
  typedef typename Iterator::reference         reference;
};
/* 特化版本,迭代器是個原生指針
 */
template <class T>
struct iterator_traits<T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

/* 這裏還要針對const T*特化
 * 否則還是依照上一個特化版本,value_type是const int而不是int
 */
template <class T>
struct iterator_traits<const T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef const T*                   pointer;
  typedef const T&                   reference;
};




當用advance函數來計算兩個迭代器間的距離時,可以獲得其迭代器類型進行相應的操作,提高效率

template <class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n, input_iterator_tag) {
  while (n--) ++i;
}

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma set woff 1183
#endif

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;
}

#if defined(__sgi) && !defined(__GNUC__) && (_MIPS_SIM != _MIPS_SIM_ABI32)
#pragma reset woff 1183
#endif

template <class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n,
                      random_access_iterator_tag) {
  i += n;
}

template <class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n) {
  __advance(i, n, iterator_category(i));
}

 

 

發佈了36 篇原創文章 · 獲贊 15 · 訪問量 5930
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章