STL學習之迭代器和trait程式設計技巧

2021-07-08 16:43:02 字數 2581 閱讀 3572

一、迭代器的概念

迭代器是stl將資料容器和演算法分開後連線的紐帶,也是泛型思維發展的必然結果。泛型演算法就是通過迭代器操作容器的,使得演算法和容器本身分離開來。

迭代器模式:提供一種方式,可以依次訪問乙個聚合物(容器)中所有元素而不暴露聚合物內部的表達方式。

迭代器類似與智慧型指標,但是它一般不會對所指向的元素進行釋放空間,因為迭代器只是在指標外面包裹一層外加一些操作。迭代器最重要編碼工作是完成一些操作符的過載,這些過載都是針對指標型別的操作,例如,++,——,*,->等,不同型別的迭代器完成的功能都不相同,詳解見下文。

迭代器定義的位置最好是在容器內,將定義的任務交給了容器的設計者,因為每一種容器都對應一種迭代器,而定義在內部也不會暴露容器的內部元素。

二、迭代器型別和trait程式設計

迭代器的型別主要有五種:value_type,catalog,reference,pointer,diffrence。分別代表這迭代器所指物件型別,迭代器型別,迭代器所指型別引用,迭代器所指型別指標,用什麼型別表示迭代器之間距離(如int型別)。如何提取這些迭代器都有的特性呢?

首先,為所有的迭代器提供乙個型別型別,每定義乙個迭代器都必須繼承該型別型別。

template

<

class

category, 

class

t, class

distance = 

ptrdiff_t

,  class

pointer = t*, 

class

reference = t&>  

struct

iterator ;  

當定義迭代器的時候,必須給定迭代器的特性。stl為提取迭代器的特性,提供了乙個模板類iterator_trait,適用於所有的迭代器和原生指標,定義如下

template

<

class

iterator>  

struct

iterator_traits  

;  //針對指標提供特化版本

template

<

class

t>  

struct

iterator_traits

;  // 針對指向常物件的指標提供特化

template

<

class

t>  

struct

iterator_traits<

const

t*>  

;  指標並非型別,因此需要偏特化成乙個模板對應指標的特性,可以看出,指標是隨機訪問迭代器型別。

迭代器的型別有五種:輸入、輸出、前向、雙向、隨機訪問五種迭代器,輸入和輸出分別唯讀和只寫,只能向前不能向後,前向迭代器可以進行讀寫,只能向前,雙向迭代器可以向前和向後移動,但每次只能移動一次,隨機訪問迭代器可以跳躍移動,與原生指標操作相同。

stl中構建了這五種類別,用於標識迭代器的類別。

// 用於標記迭代器型別

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元程式設計技術,之所以使用結構體或型別,是為了進行引數推導,將判斷在編譯期執行而非執行期,因為每個迭代器操作不同,因此需要不同的函式版本對應不同迭代器。

三、_type_trait

以上講的是迭代器的特性提取,還有型別的特性提取。型別的型別主要有五種:has_trivial_default_constructor、has_trivial_copy_constructor、has_trivial_assignment_operator、has_trivial_destructor、is_pod_type。

stl提供的模板_type_trait類

template

<

class

type>  

struct

__type_traits  

;  _true_type和_false_type是結構體,用於標記真假,也是為了用於引數推導才使用型別的。stl對每個內建型別均進行了特化,且將所有型別標記為_true_type

指標不是型別,但是有此五種特性,進行偏特化

template

<

class

t>  

struct

__type_traits

;  對於某些型別的指標可能有不同的型別,可以進行特化。

每種新定義的型別,都需要進行特化標識自己的特性,否則按照預設的全部為_false_type。

STL原始碼(2) 迭代器 trait

const iterator 不可通過迭代器改變所指的物件 一 iterator traits 演算法在使用iterator的時候需要知道迭代器指向物件的屬性,如果這裡的迭代器是乙個物件,則可以通過 直接獲取,但是如果迭代器是乙個指標,不能直接獲取。因此需要traits來獲取迭代器指向物件的屬性。二...

STL原始碼剖析學習三 迭代器與traits

stl的中心思想在於 將資料容器與演算法分開,彼此獨立設計,然後用膠合劑將他們撮合在一起。迭代器最重要的操作就是對operator 和operator 進行過載 為了不暴露容器的內部實現細節,每一種容器都有專屬的迭代器,這樣就可以把所有的實現細節封裝起來不被使用者看到。偏特化 如果模板類擁有乙個以上...

STL學習之迭代器

迭代器提供了順序訪問容器中每個元素的方法。迭代器可以使用 運算子獲得下乙個元素的迭代器,可以使用 運算子訪問當前迭代器所指向的元素。如果元素型別是結構體或類,還可以使用 運算子直接訪問該元素的乙個成員。以下是個人在學習迭代器時獲得得一些見解。輸入流迭代器用來從乙個輸入流中連續地輸入某種型別的資料,它...