1. 程式人生 > >3-迭代器

3-迭代器

iterator模式:提供一種方法,使之能夠依序尋訪某個容器所含的各個元素,而又無需暴露該聚合物內部表述方式。

   

  • 迭代器是一種smart pointer

    迭代器是一種行為像指標的物件,指標最常見的內容是 dereference 和 member access(成員訪問)

    迭代器最重要的變成工作就是對 operator* 和operator-> 進行過載

       

  • 迭代器相應的型別

    在演算法運用迭代器時,會用到迭代器的相應型別。演算法有必要宣告一個變數,以"迭代器所指物件的型別"為型別(要推匯出 *iter 的型別)。利用function template 的引數推導機制。

    要推斷出 *iter 由於func_impl() 是一個 function template,一旦被呼叫,編譯期會自動進行 template引數推導,於是匯出型別T。

       

  • Traits 程式設計技法

       

    "template引數推導機制"推而導之的只是引數,無法推導函式的返回值型別。

    可以在類中內嵌型別宣告

    typedef T value_type;

    使用的時候返回值為

    Template<class I>

    typename I::value_type

       

    迭代器所指物件的型別,稱為該迭代器的value type。

    func 的返回型別必須加上關鍵詞 typename, 因為 T 是一個template引數,它再編譯器具體現化之前,編輯器對T一無所知,換句話說,編譯器此時並不知道 MyTter<T>::value_ype 代表的是一個型別或是一個member function 或是一個data member。關鍵詞 typename 的用以在於告訴編譯器這是一個型別,如此才能順利通過編譯。

       

    並不是所有迭代器都是class type,原生指標就不是,如果不是class type,就無法為他內嵌型別。

       

  • partial specialization 偏特化的意義

       

    如果class template 擁有一個以上的template 引數,我們可以針對其中某個(並非全部)template引數進行特化工作。換句話說,我們可以在泛化設計中提供一個特化版本。

       

    partial specializtion的定義是"針對任何template引數更進一步的條件限制所設計出來的一個特化版本"

       

    有了這項利器,就可以解決內嵌型別未能解決的問題。

       

       

    這個所謂的traits的意義是,如果I定義有自己的value type, 那麼通過這個traits的作用,萃取出來的value_type 就是 I::value type

       

    最常用到的迭代器相應型別有物種 value type, difference type, pointer, referrence, interator catoagory

       

  • value type

    value type是指迭代器所指物件的型別,任何一個打算與STL演算法有完美搭配的class,都應該有自己的value type。

       

  • difference type

    difference type表示兩個迭代器之間的距離,因此它可以用來表示一個容器的最大容量。如果泛型演算法提供一個計數功能,其傳回值就是一個difference type。

       

    針對相應型別difference type, traits 的如下兩個特化版本,以C++內建的ptrdiff_t(<cstddef>標頭檔案)作為原生指標的 difference type。

       

  • Reference type

       

    迭代器分兩種: 不允許改變所指之物件內容稱為 constant iterators,例如const int * pic, 允許改變所指物件內容稱為mutable iterators。當我們對一個mutable iterators 進行提領操作時,不應該獲得一個右值,因為右值不能進行賦值操作。

       

    在C++中,如果要傳回左值,都是以by reference 方式進行的,當p 是一個 mutable iterator 時,如果其value type是T,那麼 *p 的型別應該是 T&。

       

  • Pointer type

     

    傳回一個左值,令他代表p所指之物是可能的,那麼傳回一個左值,令它代表所指之物的地址也可以.

    傳回一個pointer, 指向迭代器所指之物。

       

    Item& 便是 listiter 的 reference type, Item* 便是其 pointer type

    把這兩個型別分別加入traits

       

  • Iterator_category

       

    根據移動特性與施行操作,迭代器被分為五類

       

  • Input iterator : 這種迭代器所指的物件,不允許外界改變(read only)
  • Output iterator: write only
  • Forward iterator: 允許寫入型演算法在這種迭代器所形成的區間進行讀寫操作
  • Bidirectional iterator: 可雙向移動,某些演算法需要逆向走訪某個迭代器區間
  • Random access iterator: 前四種迭代器都只提供一部分指標算術能力(前三種 operator++ 第四種加上 operator--) 第五中覆蓋所有指標算術能力 p+n p-n p[n] p1 - p2 p1<p2

       

    箭頭表示概念(concept)和強化(refinement)的關係

       

  1. Iterator 的保證

    STL提供了一個iterators class 如下

    如果每個新設計的迭代器都繼承自它,就可以保證STL所需之規範

    Iterator class 不含任何成員,只是單純定義型別,所以繼承它不會招致任何額外的負擔,由於後三個引數有預設值,新的迭代器只需提供前兩個引數