1. 程式人生 > >advance()和distance()

advance()和distance()

一、 啟用過載函式 

引數列表光有型別,而沒有變數名——因為變數壓根兒就不會在函式內用到。為了過載而存在,主要和第五部分結合起來看。

#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));
}