STL源碼剖析-3

2.迭代器(iterators)概念和traits編程技法

STL的中心思想是將containeralgotithmn分離開,獨立設計,最後再以膠合劑把他們撮合到一塊兒。c++

  • 簡而言之traits存儲着不一樣迭代器的特性,traits對不一樣的iterators求結果,經過函數重載,模板等方式,在編譯階段,綁定到正確的方法上去。

1.迭代器

迭代器類型打通的基本方法編程

  • 不單單是指的值,會有經常使用的五種類型
    • value_type
    • difference_type
    • pointer
    • reference
      • 主要區分類型是否可變,左值OR右值
    • iterator_category
      • 根據支持的操做分爲5類
// 方法內部須要使用類型的狀況
// 迭代器所指類型(T)的傳遞,暴露func,具體實如今func_impl中
template<typename I, typename T>
void func_impl(I iter, T t) {
    T tmp; 
    // 略
}

template<typename I>
inline void func(I iter) {
    func_impl(iter, *iter);
}

//方法返回值須要使用類型的狀況
//能夠經過設置統一的聲明內嵌類型解決,可是沒法應用於原生類型例如指針
//經過特化解決

template<class I> struct iterator_traits { //stl實現的迭代器類,須要聲明內嵌類型value_type等
    typedef typename I::value_type value_type;
    typedef typename I::difference_type difference_type;
    typedef typename I::pointer pointer;
    typedef typename I::reference reference;
    typedef typename I::iterator_category iterator_category;
};

template<typename T>
struct iterator_traits<T*> {  // 指針類型特化
    typedef T value_type;
    typedef ptrdiff_t difference_type; //定義於cstddef頭文件
    typedef T* pointer;
    typedef T& reference;
    typedef random_access_iterator_tag iterator_category;
};

template<typename T>
struct iterator_traits<const T*> {  // 底層const指針類型特化
    typedef T value_type;
    typedef ptrdiff_t difference_type;
    typedef const T* pointer;
    typedef const T& reference;
    typedef random_access_iterator_tag iterator_category;
};

// STL源碼中的相關特性選擇ex:以advance爲例,經過iterator_category類型,重載__advance
__advance(i, n, iterator_category(i));  //相關使用

// iterator_category 的實現
template<class I> inline typename iterator_traits<I>::iterator_category iterator_category(const I&) {
    typedef  typename iterator_traits<I>::iterator_category category;
    return category();              // 由於category實際是一個類,實際上由於class 會有繼承關係,相關函數參數爲父類,則子類無需特化時,無需重複實現,即無需全部函數都實現5個iterator_category重載的版本
}
複製代碼
//爲了確保全部iterator都實現了5個內嵌類別,STL提供了一個基類

template<typename Category, typename T, typename Distance=ptrdiff_t, typename Pointer=T*, typename Reference=T&>
struct iterator{
    typedef Category iterator_category;
    typedef T value_type;
    typedef Distance difference_type;
    typedef Pointer pointer;
    typedef Reference reference;
};

template <typename Item>
struct ListIter: public std::iterator<std::forward_iterator_tag, Item>
{};
複製代碼

2.__type_traits

  • iterator_traits負責萃取迭代器的特性
  • __type_traits是相似iterator_traits的技法,STL將其擴展到了迭代器之外,負責萃取type的特性,主要用於優化構造,析構,拷貝構造和賦值構造
// 定義的兩個標誌,用做相關方法傳參
struct __true_type{};
struct __false_type{};
複製代碼
template<class type> struct __type_traits {
    typedef __true_type this_dummy_member_must_be_first; //和編譯器的一個約定,必須第一個,可是代碼邏輯使用不到
    
    typedef __false_type has_trivial_default_constructor;
    typedef __false_type has_trivial_copy_constructor;
    typedef __false_type has_trivial_assignment_constructor;
    typedef __false_type has_trivial_distructor;                  //前四個對應,是不是能夠省略調用的構造函數和析構函數
    typedef __false_type is_POD_type;                             //plainOldData,這些類型沒有構造和析構函數,沒有虛函數,c++基本類型都是
};

複製代碼
相關文章
相關標籤/搜索