什么是迭代器?就是提供一种方法访问容器,而不暴露容器内部的结构,方便使用者访问存取数据,由于STL采用泛型编程,迭代器又是容器和算法相结合的胶水,算法通过迭代器获取容器内部数据进行运算、排序等等,算法和容器不必知道对方结构。
五种迭代器类型,分别为只读迭代器、只写迭代器、前向迭代器、双向迭代器、随机访问迭代器
//定义五种迭代器类型
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{};
STL还定义了迭代器的基类,所有迭代器的编写,都要继承或者自己在迭代器内部定义这些类型,定义这些类型不会对你迭代器的编写造成任何负担,为STL萃取迭代器的相关类型,以及属性做类型定义。
//迭代器的基类,重写迭代器应该继承这个
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;
};
除此之外,STL还定义五种不同类型迭代器的基类
//五种迭代器的基类
template <class T, class Distance>
struct input_iterator
{
typedef input_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance>
struct output_iterator
{
typedef output_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance>
struct forward_iterator
{
typedef forward_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance>
struct bidirectional_iterator
{
typedef bidirectional_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
template <class T, class Distance>
struct random_access_iterator
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef Distance difference_type;
typedef T* pointer;
typedef T& reference;
};
答案是容器的编写者,只有容器的编写者才了解其内部结构的构成,在编写迭代器的时候,应该遵循迭代器编写规范,在内部定义相关的类型,分别是
iterator_category //迭代器类型
value_type //迭代器所指类型
difference_type //迭代器距离类型
pointer //迭代器所指类型的指针类型
reference; //所指的引用类型
STL还使用traits技法,为迭代器相关类型的萃取定义了许多类模板
//迭代器相关类型的萃取
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;
};
//对内置指针类型的特例化
template <class T>
struct iterator_traits
{
typedef random_access_iterator_tag 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*>
{
typedef random_access_iterator_tag iterator_category;
typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;
};
//一些函数模板,获取迭代器定义的相关类型
template <class Iterator>
inline typename iterator_traits:: iterator_category
iterator_category(const Iterator&)
{
return iterator_traits::iterator_category();
}
template <class Iterator>
inline typename iterator_traits::difference_type*
distance_type(const Iterator&)
{
return static_cast<typename iterator_traits::difference_type*>(0);
}
template <class Iterator>
inline typename iterator_traits::value_type*
value_type(const Iterator&)
{
return static_cast<typename iterator_traits::value_type*>(0);
}
由于不用类型的迭代器支持不同的访问方式
Input iterator(输入迭代器)
读,不能写
只支持自增运算
Output iterator(输出迭代器) ;
写,不能读
只支持自增运算
Forward iterator(前向迭代器)
读和写;
只支持自增运算
Bidirectional iterator(双向迭代器) ;
读和写
支持自增和自减运算
Random access iterator(随机访问迭代器)
读和写;
支持完整的迭代器算术运算
所以对于迭代器距离的计算,有不同的函数
//根据迭代器类型的不同,迭代器距离的计算也不同
template <class InputIterator, class Distance>
inline void __distance(InputIterator __first, InputIterator __last,
Distance& __n, input_iterator_tag)
{
while (__first != __last)
{
++__first;
++__n;
}
}
template <class RandomAccessIterator, class Distance>
inline void __distance(RandomAccessIterator __first,
RandomAccessIterator __last,
Distance& __n, random_access_iterator_tag)
{
__n += __last - __first;
}
template <class InputIterator, class Distance>
inline void distance(InputIterator __first,
InputIterator __last, Distance& __n)
{
__distance(__first, __last, __n, iterator_category(__first));
}
//根据迭代器类型的不同调用不同的迭代器距离函数,提高效率
template <class InputIterator, class Distance>
inline void advance(InputIterator& _i, Distance _n)
{
_advance(_i, _n, iterator_category(_i));
}
template <class InputIter, class Distance>
inline void __advance(InputIter& __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,
random_access_iterator_tag) {
__i += __n;
}