STL源碼剖析(迭代器)

來源:互聯網
上載者:User

標籤:++   操作   減法   選擇   out   版本   nbsp   str   false   

在STL中,容器跟演算法是分開設計的,演算法是通過迭代器來對容器進行操作的。

在演算法運用迭代器的時候,可能會用到其相應的型別,例如傳回值為容器中元素的型別,又或者說根據迭代器的類型來選擇更好的演算法等等。

為了實現這一點,還有為了相容內建型別的迭代器(vector迭代器直接使用原生pointer),STL使用了traits技法,用於提取迭代器的特性(相應的型別)。

 

1.首先在iterator中typedef相應的型別

 1 // 這是迭代器的基類 所有迭代器必須定義這5種型別 2 template<class Category, class T, class Distance = ptrdiff_t, 3 class Pointer = T*, class Reference = T&> 4 struct iterator { 5     typedef Category iterator_category; 6     typedef T value_type; 7     typedef Distance difference_type; 8     typedef Pointer pointer; 9     typedef Reference reference;10 };
View Code

2.定義萃取器iter_traits

1 // 以迭代器為模板參數,用於萃取相應的型別2 template <class Iterator>3 struct iter_traits {4     typedef typename Iterator::iterator_category iterator_category;5     typedef typename Iterator::value_type value_type;6     typedef typename Iterator::difference_type difference_type;7     typedef typename Iterator::pointer pointer;8     typedef typename Iterator::reference reference;9 };
View Code

3.定義相應的偏特化版本(這就是為什麼要使用iter_traits封裝多一層),因為內建型別的迭代器並不是class,不能定義相應的型別。

 1 // 原生指標的偏特化版 2 template <class T> 3 struct iter_traits<T*> { 4     typedef typename random_access_iter_tag iterator_category; 5     typedef typename T value_type; 6     typedef typename ptrdiff_t difference_type; 7     typedef typename T* pointer; 8     typedef typename T& reference; 9 };10 11 // 原生const的偏特化版12 template <class T>13 struct iter_traits<const T*> {14     typedef typename random_access_iter_tag iterator_category;15     typedef typename T value_type;16     typedef typename ptrdiff_t difference_type;17     typedef typename const T* pointer;18     typedef typename const T& reference;19 };
View Code

4.5種迭代器類型,只是一個標誌,用於根據萃取出來的iterator_category來選擇相應的演算法。

1 struct input_iter_tag {};2 struct output_iter_tag {};3 struct forward_iter_tag : public input_iter_tag {};4 struct bidirectional_iter_tag : public forward_iter_tag {};5 struct random_access_iter_tag  : public bidirectional_iter_tag {};
View Code

 

下面是distance()的實現,展示了怎麼使用traits萃取相應的型別。

 1 // input迭代器只支援operator++ 2 template<class InputIterator> 3 inline typename iter_traits<InputIterator>::difference_type 4 __distance(InputIterator first, InputIterator last, input_iter_tag) 5 { 6     iter_traits<InputIterator>::difference_type n = 0; 7     while (first != last) 8     { 9         first++;10         n++;11     }12     return n;13 }14 15 // random access迭代器支援迭代器之間的加減法16 template<class RandomAccessIterator>17 inline typename iter_traits<RandomAccessIterator>::difference_type18 __distance(RandomAccessIterator first, RandomAccessIterator last, random_access_iter_tag)19 {20     return last - first;21 }22 23 // 根據迭代器的iterator_category來調用適合的版本24 template<class Iterator>25 inline typename iter_traits<Iterator>::difference_type26 distance(Iterator first, Iterator last)27 {28     return __distance(first, last, iter_traits<Iterator>::iterator_category());29 }
View Code

 

 

STL的__type_traits也是使用traits技法,它可以萃取一個class是否有不重要的建構函式、是否為POD類型等等。

 1 // __type_traits也是運用traits技術 2 struct __true_type {}; 3 struct __false_type {}; 4  5 template <class type> 6 struct __type_traits { 7     // 預設為false  可以實現自己的偏特化版本 8     // 內建類型的偏特化版本定義在stl_config.h中  都是__true_type 9     typedef __false_type    has_trivial_default_constructor;10     typedef __false_type    has_trivial_copy_constructor;11     typedef __false_type    has_trivial_assignment_operator;12     typedef __false_type    has_trivial_destructor;13     typedef __false_type    is_POD_type;14 };
View Code

自訂的類型可以定義相應的偏特化版本,例如定義is_POD_type為__true_type,STL會在元素析構的時候只進行記憶體回收,而不調用解構函式以用來提高效率。

STL源碼剖析(迭代器)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.