迭代器相关辅助函数advance()和distance()

版权声明:私藏源代码是违反人性的罪恶行为!博客转载无需告知,学无止境。 https://blog.csdn.net/qq_41822235/article/details/83076790

一、 激活重载函数 

参数列表光有类型,而没有变量名——因为变量压根儿就不会在函数内用到。为了重载而存在,主要和第五部分结合起来看。

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

猜你喜欢

转载自blog.csdn.net/qq_41822235/article/details/83076790