iterator充当容器与算法之间的桥梁,使算法不需要了解具体的算法底层实现即能操作容器中的元素。迭代器可以理解为智能指针,原生指针(native pointer)也是迭代器的一种。
stl_iterator_base.h这个文件定义了迭代器的类型,以及针对不同类型迭代器的associated types。(所回答的问题)
iterator_category迭代器一共有五种类型(iterator_category)
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{}; //随机访问
associated type
迭代器所回答的问题,有iterator_category value_type difference_type pointer reference五个
下面是针对五种基础类型的迭代器进行定义的问题答案:
以input_iterator_tag为例:
templatestruct input_iterator { typedef input_iterator_tag iterator_category; // 迭代器类别 typedef _Tp value_type; // 解引用所得到的值的类型 typedef _Distance difference_type; // 迭代器之间的距离 typedef _Tp* pointer; // 指向被迭代类型的指针 typedef _Tp& reference; // 被迭代类型的引用类型 }; template inline input_iterator_tag iterator_category(const input_iterator<_Tp, _Distance>&) { return input_iterator_tag(); } template inline _Tp* value_type(const input_iterator<_Tp, _Distance>&) { return (_Tp*)(0); } template inline _Distance* distance_type(const input_iterator<_Tp, _Distance>&) { return (_Distance*)(0); }
关于value_type distance_type iterator_category 的回答方式,除output_iterator_tag外其余几种类型的迭代器均一致,在此不再罗列。仅列出output_iterator_tag相关回答函数
struct output_iterator {
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
};
//比起其他类型,无_Distance>&参数
inline output_iterator_tag iterator_category(const output_iterator&)
{ return output_iterator_tag(); }
//output_iterator_tag 无 value_type
//output_iterator_tag 无 distance_type
template struct forward_iterator {
typedef forward_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
template struct bidirectional_iterator {
typedef bidirectional_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
template struct random_access_iterator {
typedef random_access_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Tp& reference;
};
advance/distance
迭代器的类型不同,其所能移动的方式也不同,进而在移动(advance)/距离(distance)实现的方式上也有着差距:
advancetemplatedistanceinline void advance(_InputIterator& __i, _Distance __n) { __STL_REQUIRES(_InputIterator, _InputIterator); __advance(__i, __n, iterator_category(__i)); }//总体调用这个函数 //根据iterator_category 的差异 定义不同类型迭代器的行为 //类似于 vector中的迭代器 支持跳跃,直接移动相应的距离 template inline void __advance(_RandomAccessIterator& __i, _Distance __n, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); __i += __n; // 双向,跳跃前进,加上标记 random_access_iterator_tag } //类似于slist、stack、queue中的迭代器,仅能单向单步移动 template inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) { while (__n--) ++__i; // 单向,加上标记 input_iterator_tag } //类似于list、deque中的迭代器,支持双向 单步移动 template inline void __advance(_BidirectionalIterator& __i, _Distance __n, bidirectional_iterator_tag) { __STL_REQUIRES(_BidirectionalIterator, _BidirectionalIterator); if (__n >= 0) // 双向,加上标记 bidirectional_iterator_tag while (__n--) ++__i; else while (__n++) --__i; }
templatenative pointerinline void distance(_InputIterator __first, _InputIterator __last, _Distance& __n) { __STL_REQUIRES(_InputIterator, _InputIterator); __distance(__first, __last, __n, iterator_category(__first)); }//总体调用这个函数 //根据iterator_category 的差异 定义不同类型迭代器的行为 //vector中的 随机访问迭代器 可以直接通过迭代器相减计算距离 template inline void __distance(_RandomAccessIterator __first, _RandomAccessIterator __last, _Distance& __n, random_access_iterator_tag) { __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator); __n += __last - __first; } //其余类型迭代器需要单步移动至重合 template inline void __distance(_InputIterator __first, _InputIterator __last, _Distance& __n, input_iterator_tag) { while (__first != __last) { ++__first; ++__n; } }
前文说原生指针也是一种迭代器,故在此对其也进行了相应的回答
templatestd::iteratorinline random_access_iterator_tag iterator_category(const _Tp*) { return random_access_iterator_tag(); }//原生指针支持随机访问 template inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); } template inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); }
除了默认的五种类型的迭代器外,还规定了另外一种std::iterator该迭代器用于支撑用户自定义的迭代器相应规则的答案。
#ifdef __STL_USE_NAMESPACES templatetraits机制struct iterator { typedef _Category iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Pointer pointer; typedef _Reference reference; }; #endif
通过萃取机制,使得使用更加灵活。
iterator_traits 负责萃取迭代器的特性,__type_traits 负责萃取类型的特性。
iterator_traitstemplatestruct 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; }; // native_pointer template struct iterator_traits<_Tp*> { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; // C++ 内建的 ptrdiff_t 类型 typedef _Tp* pointer; typedef _Tp& reference; }; // native_pointer-to-const template struct iterator_traits { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef ptrdiff_t difference_type; typedef const _Tp* pointer; typedef const _Tp& reference; };
iterator_category以下是通过萃取机去询问相应问题
获取迭代器类型
templatedifference_typeinline typename iterator_traits<_Iter>::iterator_category __iterator_category(const _Iter&) { typedef typename iterator_traits<_Iter>::iterator_category _Category; return _Category(); } template inline typename iterator_traits<_Iter>::iterator_category iterator_category(const _Iter& __i) { return __iterator_category(__i); }
获取迭代器间距离
templatevalue_typeinline typename iterator_traits<_Iter>::difference_type* __distance_type(const _Iter&) { return static_cast ::difference_type*>(0); } template inline typename iterator_traits<_Iter>::difference_type* distance_type(const _Iter& __i) { return __distance_type(__i); }
获取值类型
template__type_traitsinline typename iterator_traits<_Iter>::value_type* __value_type(const _Iter&) { return static_cast ::value_type*>(0); } template inline typename iterator_traits<_Iter>::value_type* value_type(const _Iter& __i) { return __value_type(__i); }
提供了一种机制,允许针对不同的类型属性,在编译时期完成函数派送(function dispatch)
true/false// class 没有任何成员,不会带来额外负担,却又能够标示真假。
struct __true_type {
};
struct __false_type {
};
基础traits定义
templatestruct __type_traits { typedef __true_type this_dummy_member_must_be_first; typedef __false_type has_trivial_default_constructor; //有 平凡 默认 构造函数 typedef __false_type has_trivial_copy_constructor; //有 平凡 拷贝构造函数 typedef __false_type has_trivial_assignment_operator;//有 平凡 赋值操作 typedef __false_type has_trivial_destructor;//有 平凡 析构函数 typedef __false_type is_POD_type; // Plain Old Data 是普通旧数据 }; //默认均为false类型
除了默认外,对传统数据类型进行了重载,进行重载的类型有:
bool、 char 、signed char、unsigned char、wchar_t、short、unsigned short、int、unsigned int、long、unsigned long、long long、unsigned long long、float、double、long double、char*、signed char*、unsigned char*、const char*、const signed char*、const unsigned char*、template
_Tp*
以上类型默认__type_traits各成员均为true
除此之外,关于数组大小的限制,要求是int型,故也有_Is_integer类型萃取。
raw_storage_iteratorbool、 char 、signed char、unsigned char、wchar_t、short、unsigned short、int、unsigned int、long、unsigned long、long long、unsigned long long
使标准算法可以将结果存储在未初始化的内存中。其相关基础定义如下
templateauto_ptrclass raw_storage_iterator { protected: _ForwardIterator _M_iter; public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit raw_storage_iterator(_ForwardIterator __x) : _M_iter(__x) {} raw_storage_iterator& operator*() { return *this; } raw_storage_iterator& operator=(const _Tp& __element) { construct(&*_M_iter, __element); return *this; } raw_storage_iterator<_ForwardIterator, _Tp>& operator++() { ++_M_iter; return *this; } raw_storage_iterator<_ForwardIterator, _Tp> operator++(int) { raw_storage_iterator<_ForwardIterator, _Tp> __tmp = *this; ++_M_iter; return __tmp; } }; template inline output_iterator_tag iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&) { return output_iterator_tag(); }
前面说道 迭代器可以理解为智能指针,这里将介绍一下智能指针。
基础结构auto_ptr在c++11弃用,在c++17已移出
进行封装后的原生指针。
template构造函数class auto_ptr { private: _Tp* _M_ptr; public: typedef _Tp element_type; }
explicit关键字用于防止隐式类型转换。
explicit auto_ptr(_Tp* __p = 0) __STL_NOTHROW : _M_ptr(__p) {}
auto_ptr(auto_ptr& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
template auto_ptr(auto_ptr<_Tp1>& __a) __STL_NOTHROW : _M_ptr(__a.release()) {}
_Tp* release() __STL_NOTHROW {
_Tp* __tmp = _M_ptr;
_M_ptr = 0;
return __tmp;
}
拷贝赋值
后续实现的功能除有__STL_NOTHROW修饰外,即正常实现,不过多叙述
auto_ptr& operator=(auto_ptr& __a) __STL_NOTHROW {
if (&__a != this) {
delete _M_ptr;
_M_ptr = __a.release();
}//防止自赋值导致 先资源释放 后 无法赋值
return *this;
}
template
auto_ptr& operator=(auto_ptr<_Tp1>& __a) __STL_NOTHROW {
if (__a.get() != this->get()) {
delete _M_ptr;
_M_ptr = __a.release();
}
return *this;
}
_Tp* get() const __STL_NOTHROW {
return _M_ptr;
}
iterator adapter
back_insert_iterator
用于在指定容器的末尾处添加新元素。它的唯一数据成员是指向容器的指针,不指向容器内的任何元素,故++操作对其没有意义。由于它会调用底层容器的push_back()函数,故其只适用于含有该函数的容器。
templatefront_insert_iteratorclass back_insert_iterator { protected: _Container* container; public: typedef _Container container_type; //所包含的容器类型 typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit back_insert_iterator(_Container& __x) : container(&__x) {} back_insert_iterator<_Container>& operator=(const typename _Container::value_type& __value) { container->push_back(__value); return *this; }//调用底层容器的push_back back_insert_iterator<_Container>& operator*() { return *this; } back_insert_iterator<_Container>& operator++() { return *this; } back_insert_iterator<_Container>& operator++(int) { return *this; } //++运算符直接返回自身,能使用但并未指向下一个。 }; #ifndef __STL_CLASS_PARTIAL_SPECIALIZATION //基础iterator类型 template inline output_iterator_tag iterator_category(const back_insert_iterator<_Container>&) { return output_iterator_tag(); } #endif //对外接口 传入的是支持push_back的容器 如 vector template inline back_insert_iterator<_Container> back_inserter(_Container& __x) { return back_insert_iterator<_Container>(__x); }
除了只能调用push_front()函数与back_insert_iterator完全一致。也提供对外接口front_inserter
insert_iterator该适配器允许在任意位置插入元素。故其底层比头插、尾插的类模板多一个迭代器用来调整插入位置。
templateclass insert_iterator { protected: _Container* container; typename _Container::iterator iter; };
同样的,对外接口inserter除了要传容器外,还需要传一个迭代器(指明插入位置)
reverse_bidirectional_iterator双向翻转迭代器,可双向访问。++ -- 和实际恰好相反。*iter原本返回的是左侧元素,现在也随之翻转,返回右侧。由于是bidirectional_iterator_tag的翻转版,仅支持单步移动(类似于list)
class reverse_bidirectional_iterator {
typedef reverse_bidirectional_iterator
<_BidirectionalIterator, _Tp, _Reference, _Distance> _Self;
protected:
_BidirectionalIterator current;
public:
typedef bidirectional_iterator_tag iterator_category;
typedef _Tp value_type;
typedef _Distance difference_type;
typedef _Tp* pointer;
typedef _Reference reference;
reverse_bidirectional_iterator() {}
explicit reverse_bidirectional_iterator(_BidirectionalIterator __x)
: current(__x) {}
_BidirectionalIterator base() const { return current; }//不打破封装得到底层
_Reference operator*() const {
_BidirectionalIterator __tmp = current;
return *--__tmp;
}//正常end()的返回形式,不过--已重载
#ifndef __SGI_STL_NO_ARROW_OPERATOR
pointer operator->() const { return &(operator*()); }
#endif
_Self& operator++() {
--current;
return *this;
}//反向移动
_Self operator++(int) {
_Self __tmp = *this;
--current;
return __tmp;
}
_Self& operator--() {
++current;
return *this;
}
_Self operator--(int) {
_Self __tmp = *this;
++current;
return __tmp;
}
};
//迭代器类型 bidirectional_iterator_tag
template
inline bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator
<_BidirectionalIterator, _Tp, _Reference, _Distance>&)
{
return bidirectional_iterator_tag();
}
//value_type
template
inline _Tp* value_type(const reverse_bidirectional_iterator
<_BidirectionalIterator, _Tp,_Reference, _Distance>&)
{
return (_Tp*) 0;
}
//distance_type
template
inline _Distance* distance_type(const reverse_bidirectional_iterator
<_BidirectionalIterator, _Tp,_Reference, _Distance>&)
{
return (_Distance*) 0;
}
//运算符重载 ==
template
inline bool operator==(
const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __x,
const reverse_bidirectional_iterator<_BiIter, _Tp, _Ref, _Distance>& __y)
{
return __x.base() == __y.base();
}
//同理 还重载了!= 返回为 !(x==y)
reverse_iterator
同样,是双向均翻转的迭代器。
与reverse_bidirectional_iterator不同的是其翻转的是random_access_iterator_tag,故支持移动多个位置及随机访问。
_Self operator+(_Distance __n) const {
return _Self(current - __n);
}
_Self& operator+=(_Distance __n) {
current -= __n;
return *this;
}
_Self operator-(_Distance __n) const {
return _Self(current + __n);
}
_Self& operator-=(_Distance __n) {
current += __n;
return *this;
}
_Reference operator[](_Distance __n) const { return *(*this + __n); }
istream_iterator
将迭代器绑定到一个 istream 对象上,使之具备输入能力。
templateostream_iteratorclass istream_iterator { protected: istream* _M_stream; _Tp _M_value; bool _M_end_marker; void _M_read() { _M_end_marker = (*_M_stream) ? true : false; if (_M_end_marker) *_M_stream >> _M_value; _M_end_marker = (*_M_stream) ? true : false; } public: istream_iterator() : _M_stream(&cin), _M_end_marker(false) {} istream_iterator(istream& __s) : _M_stream(&__s) { _M_read(); } reference operator*() const { return _M_value; } pointer operator->() const { return &(operator*()); } }; //迭代器类型 input_iterator_tag template inline input_iterator_tag iterator_category(const istream_iterator<_Tp, _Dist>&) { return input_iterator_tag(); }
将迭代器绑定到一个 ostream 对象上,使之具备输出能力。
templateistreambuf_iteratorclass ostream_iterator { protected: ostream* _M_stream; const char* _M_string; public: ostream_iterator(ostream& __s) : _M_stream(&__s), _M_string(0) {} ostream_iterator(ostream& __s, const char* __c) : _M_stream(&__s), _M_string(__c) {} ostream_iterator<_Tp>& operator=(const _Tp& __value) { *_M_stream << __value; if (_M_string) *_M_stream << _M_string; return *this; } };
由于isteam_iterator采用operator>>来读取,而operator>>会忽略空格。因此考虑直接在缓冲区中读取。
templatemutable关键字class istreambuf_iterator : public iterator { public: typedef _CharT char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; typedef basic_streambuf<_CharT, _Traits> streambuf_type; typedef basic_istream<_CharT, _Traits> istream_type; public: //赋值及*iter istreambuf_iterator(streambuf_type* __p = 0) { this->_M_init(__p); } istreambuf_iterator(istream_type& __is) { this->_M_init(__is.rdbuf()); } char_type operator*() const { return _M_is_initialized ? _M_c : _M_dereference_aux(); } private: streambuf_type* _M_buf; mutable _CharT _M_c; mutable bool _M_eof : 1; mutable bool _M_is_initialized : 1; }; template _CharT istreambuf_iterator<_CharT, _Traits>::_M_dereference_aux() const { this->_M_getc(); //getc函数获取到缓冲区内容 return _M_c; } //++ istreambuf_iterator& operator++() { this->_M_nextc(); return *this; } istreambuf_iterator operator++(int) { if (!_M_is_initialized) _M_postincr_aux(); istreambuf_iterator __tmp = *this; this->_M_nextc(); return __tmp; } void _M_nextc() { int_type __c = _M_buf->snextc(); _M_c = traits_type::to_char_type(__c); _M_eof = traits_type::eq_int_type(__c, traits_type::eof()); _M_is_initialized = true; }
在const函数中,原则上不能够修改任意变量值。而如果变量是mutable关键字修饰时,则可以在const函数中进行修改。
ostreambuf_iteratormutable只能够用于一个类的非静态数据成员
同理,将数据流出至缓冲区。无++运算符(返回自身)
templateclass ostreambuf_iterator : public iterator { public: typedef _CharT char_type; typedef _Traits traits_type; typedef typename _Traits::int_type int_type; typedef basic_streambuf<_CharT, _Traits> streambuf_type; typedef basic_ostream<_CharT, _Traits> ostream_type; public: ostreambuf_iterator(streambuf_type* __buf) : _M_buf(__buf), _M_ok(__buf) {} ostreambuf_iterator(ostream_type& __o) : _M_buf(__o.rdbuf()), _M_ok(__o.rdbuf() != 0) {} ostreambuf_iterator& operator=(char_type __c) { _M_ok = _M_ok && !traits_type::eq_int_type(_M_buf->sputc(__c), traits_type::eof()); return *this; } ostreambuf_iterator& operator*() { return *this; } ostreambuf_iterator& operator++() { return *this; } ostreambuf_iterator& operator++(int) { return *this; } bool failed() const { return !_M_ok; } private: streambuf_type* _M_buf; bool _M_ok; };



