advance()和distance()
阿新 • • 發佈:2018-12-15
一、 啟用過載函式
引數列表光有型別,而沒有變數名——因為變數壓根兒就不會在函式內用到。為了過載而存在,主要和第五部分結合起來看。
#include<cstddef> //為了引入 typedef int ptrdiff_t 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<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; };
三、 型別萃取器設計
“榨汁機”是如何設計的呢?
template<class Iterator> struct iterator_traits{ typedef typename Iterator::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; }; //關於原生指標(pointer-to-non-const)的偏特化版本 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; }; //關於原生指標(pointer-to-const)的偏特化版本 template<class T> struct iterator_traits<const T*> { typedef random_access_iterator_tag iterator_category; typedef T value_type; typedef ptrdiff_t pointer; typedef const T* pointer; typedef const T& reference; };
四、 全域性函式
這些典型的全域性函式在本篇部落格中實際上是不重要的,但是在STL庫中是很關鍵的!
//求出迭代器的型別
template<class Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&) {
typedef typename iterator_traits<Iterator>::iterator_category category;
return category();
}
//決定迭代器的distance_type
template<class Iterator>
inline typename iterator_traits<Iterator>::difference_type*
distance_type(const Iterator&) {
return static_cast<typename iterator_traits<Iterator>::difference_type*>(0);
}
//決定迭代器的value_type
template<class Iterator>
inline typename iterator_traits<Iterator>::value_type*
value_type(const Iterator&) {
return static_cast<typename iterator_traits<Iterator>::value_type*>(0);
}
五、實現distance()
5.1 過載函式__distance()
template<class InputIterator>
inline typename 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 RandomAccessIterator>
inline typename iterator_traits<RandomAccessIterator>::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last,
random_access_iterator_tag) {
return last - first;
}
5.2 介面distance()
template<class InputIterator>
inline typename iterator_traits<InputIterator>::difference_type
distance(InputIterator first, InputIterator last) {
typedef typename
iterator_traits<Iterator>::iterator_category category;
return __distance(first, last, category());
}
六、實現advance()
6.1 過載函式__advance()
template<class InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n,
input_iterator_tag) {
while (n--)++i;
}
template<class BidirectionalIterator, class Distance>
inline void __advance(BidirectionalIterator& i, Distance n,
bidirectional_iterator_tag)
{
if (n >= 0)
while (n--)++i;
else
while (n++)--i;
}
template<class RandomAccessIterator, class Distance>
inline void __advance(RandomAccessIterator& i, Distance n,
bidirectional_iterator_tag) {
i += n;
}
6.2 介面advance()
template<class InputIterator, class Distance>
inline void advance(InputIterator&i, Distance n) {
__advance(i, n, iterator_category(i));
}