標籤:iterator traits
//5種迭代器,為了啟用重載機制,定義的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{};
為了定義自己的迭代器,可以繼承自下面的iterator類,避免迭代器型別的未定義。
//Base class for iterator classtemplate <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;};
iterator_traits類,就是一些typedef,相當於就是將迭代器的最本質的類型忠實的呈現出來。這裡值得注意的是,要使得這個迭代器忠實的完成這項工作,那麼各個迭代器的定義就必須定義相應的5個性別。value_type difference_type iterator_category pointer reference .
template<class Iterator>struct iterator_traits{ typedef typename 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;};
然而這對於指標而言是不可行的,因為指標沒有結構體,我們無法在其中定義這5個型別,於是針對指標,我們定義了iterator_traits的特化版本。
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;};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; };
註:根據指標指向 的內容是否可以改變,定義了上述的兩種特化版本。
下面的函數則是直接返回各個型別的類型:
template<class Iterator>inline typename iterator_traits<Iterator>::iterator_categoryiterator_category(const Iterator&){ typedef typename iterator_traits<Iterator>::iterator_category category; return category(); //random_access_iterator_tag or bidirectional_iterator_tag ...}//pointer to the difference_typetemplate< class Iterator>inline typename iterator_traits<Iterator>::difference_type*distance_type (const Iterator &){ return static_cast<typename iterator_traits<Iterator>::difference_type *>(0);}template< class Iterator>inline typename iterator_traits<Iterator>::value_type *distance_type (const Iterator &){ return static_cast<typename iterator_traits<Iterator>::value_type* > (0);}
distance函數在上述traits下的實現代碼:
//distance functiontemplate<class InputIterator>inline iterator_traits<InputIterator>::difference_type__distance(InputIterator first, InputIterator last, input_iterator_tag){ iterator_traits<InputIterator>::difference_type n=0; while(first != last) { ++first;++n; } return n;}template<class RandomIterator>inline typename iterator_traits<RandomIterator>::difference_type__distance(RandomIterator first, RandomIterator last, random_access_iterator_tag){ return last-first;}//user template<class InputIterator>inline iterator_traits<InputIterator>::difference_typedistance(InputIterator first, InputIterator last){ typedef typename iterator_traits<InputIterator>::iterator_category category; return __distance(first,last,category());//category()構造一個臨時對象,進行參數推導,決定重載函數。}
參考:STL源碼剖析