advance()函数

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

目录

一、 迭代器 

二、 类型萃取机 

2.1 处理类实现的迭代器

2.2 处理原生指针实现的迭代器

三、 advance 

3.1 iterator_category

3.2 激活重载机制 

3.3 实现advance函数


                                                            --------参考文献   侯捷.STL源码剖析[M].武汉:华中科技大学出版社,2002.6:90-94.


一、 迭代器 

#include<cstddef>

template<typename T>
class iter
{
public:
	typedef iter iterator_category;		//自身类型
	typedef T value_type;		//相关类型
	typedef ptrdiff_t difference_type;		//距离 此处是int
	typedef T* pointer;		//指针类型
	typedef T& reference;	//引用类型
};

部分迭代器是用原生指针(pointer-to-const和pointer-to-non-const)实现的!


二、 类型萃取机 

类型萃取机是与迭代器配套使用的。

2.1 处理类实现的迭代器

template<class I>
struct iterator_traits
{
	typedef typename I::iterator_category iterator_category;
	typedef typename I::value_type value_type;
	typedef typename I::difference_type difference_type;
	typedef typename I::pointer  pointer;
	typedef typename I::reference reference;
};

2.2 处理原生指针实现的迭代器

部分迭代器使用原生指针(pointer-to-const和pointer-to-non-const)实现的,故而没有类作用域,需要特殊处理: 

template<class T>
struct iterator_traits<T*>		//剔除指针类型
{
	typedef T* iterator_category;
	typedef T value_type;
	typedef ptrdiff_t difference_type;
	typedef T*  pointer;
	typedef T& reference;
};


template<class T>
struct iterator_traits<const T*>		//剔除指针类型以及const修饰
{
	typedef T* iterator_category;
	typedef T value_type;
	typedef ptrdiff_t difference_type;
	typedef T*  pointer;
	typedef T& reference;
};

三、 advance 

3.1 iterator_category

根据移动特性和行为,迭代器被分为5类:

  • Input Iterator:这种迭代器所指向的对象,不允许外界改变。只读(read only)。
  • Output Iterator:只写(write only)。
  • Forward Iterator:允许“写入型”算法(例如replace())在此种迭代器所形成的区间上进行读写操作。
  • Bidirectional Iterator:可双向移动。某些算法需要逆向走访迭代器区间(例如逆向拷贝某范围内的元素),可以使用Bidirectional Iterator。
  • Random Access Iterator:前四种迭代器都只供应一部分指针算术能力(前三种支持operator++,第四种再加上operator--),第五种则涵盖所有指针算术能力,包括p+n, p-n, p[n], p1-p2, p1<p2。

3.2 激活重载机制 

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 InputIterator, class Distance>
inline void __advance(InputIterator& i, Distance n,			//前进
	input_iterator_tag)		//第三个参数是没有参数名
{
	while (n--)++i;
}

template<class ForwardIterator, class Distance>
inline void __advance(ForwardIterator& i, Distance n,		//类似于有一个接口,本质还是前进
	forward_iterator_tag)
{
	__advance(i, n, input_iterator_tag());
}

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,
	random_access_iterator_tag)
{
	i += n;		//双向,跳跃
}

3.3 实现advance函数

值得注意的是,到底是何种迭代器在编译期就能确定下来,而不用等到运行时,以提高效率。

template<class InputIterator, class Distance>
inline void advance(InputIterator& i, Distance n)
{
	typedef typename iterator_traits<InputIterator>::iterator_category category;
	__advance(i, n, category());    //重载时,编译期已经能确定调用哪个函数
}

猜你喜欢

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