版权声明:私藏源代码是违反人性的罪恶行为!博客转载无需告知,学无止境。 https://blog.csdn.net/qq_41822235/article/details/83057426
目录
--------参考文献 侯捷.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()); //重载时,编译期已经能确定调用哪个函数
}