SGISTL源码-迭代器 笔记

iterator

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为例:

template <class _Tp, class _Distance> struct input_iterator {
    typedef input_iterator_tag iterator_category; 	// 迭代器类别
    typedef _Tp                value_type;	// 解引用所得到的值的类型
    typedef _Distance          difference_type;	// 迭代器之间的距离
    typedef _Tp*               pointer;	// 指向被迭代类型的指针
    typedef _Tp&               reference;   // 被迭代类型的引用类型
};
template <class _Tp, class _Distance> 
inline input_iterator_tag  iterator_category(const input_iterator<_Tp, _Distance>&)
{ return input_iterator_tag(); }
template <class _Tp, class _Distance> 
inline _Tp* value_type(const input_iterator<_Tp, _Distance>&)
  { return (_Tp*)(0); }
template <class _Tp, class _Distance> 
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 <class _Tp, class _Distance> struct forward_iterator {
    typedef forward_iterator_tag iterator_category;
    typedef _Tp                  value_type;
    typedef _Distance            difference_type;
    typedef _Tp*                 pointer;
    typedef _Tp&                 reference;
};

template <class _Tp, class _Distance> struct bidirectional_iterator {
    typedef bidirectional_iterator_tag iterator_category;
    typedef _Tp                        value_type;
    typedef _Distance                  difference_type;
    typedef _Tp*                       pointer;
    typedef _Tp&                       reference;
};

template <class _Tp, class _Distance> 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)实现的方式上也有着差距:

advance
template <class _InputIterator, class _Distance>
    inline void advance(_InputIterator& __i, _Distance __n) {
    __STL_REQUIRES(_InputIterator, _InputIterator);
    __advance(__i, __n, iterator_category(__i));
}//总体调用这个函数
//根据iterator_category 的差异  定义不同类型迭代器的行为

//类似于 vector中的迭代器 支持跳跃,直接移动相应的距离
template <class _RandomAccessIterator, class _Distance>
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 <class _InputIter, class _Distance>
inline void __advance(_InputIter& __i, _Distance __n, input_iterator_tag) {
    while (__n--) ++__i;  // 单向,加上标记 input_iterator_tag 
}

//类似于list、deque中的迭代器,支持双向 单步移动
template <class _BidirectionalIterator, class _Distance>
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;
}
distance
template <class _InputIterator, class _Distance>
inline void distance(_InputIterator __first, 
                         _InputIterator __last, _Distance& __n)
{
    __STL_REQUIRES(_InputIterator, _InputIterator);
    __distance(__first, __last, __n, iterator_category(__first));
}//总体调用这个函数
//根据iterator_category 的差异  定义不同类型迭代器的行为

//vector中的 随机访问迭代器 可以直接通过迭代器相减计算距离
template <class _RandomAccessIterator, class _Distance>
inline void __distance(_RandomAccessIterator __first, 
                       _RandomAccessIterator __last, 
                       _Distance& __n, random_access_iterator_tag)
{
    __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
    __n += __last - __first;
}
//其余类型迭代器需要单步移动至重合
template <class _InputIterator, class _Distance>
inline void __distance(_InputIterator __first, _InputIterator __last,
                       _Distance& __n, input_iterator_tag)
{
    while (__first != __last) { ++__first; ++__n; }
}

native pointer

前文说原生指针也是一种迭代器,故在此对其也进行了相应的回答

template <class _Tp>
inline random_access_iterator_tag iterator_category(const _Tp*)
{ return random_access_iterator_tag(); }//原生指针支持随机访问
template <class _Tp>
inline _Tp* value_type(const _Tp*) { return (_Tp*)(0); }
template <class _Tp>
inline ptrdiff_t* distance_type(const _Tp*) { return (ptrdiff_t*)(0); }
std::iterator

除了默认的五种类型的迭代器外,还规定了另外一种std::iterator该迭代器用于支撑用户自定义的迭代器相应规则的答案。

#ifdef __STL_USE_NAMESPACES
template <class _Category, class _Tp, class _Distance = ptrdiff_t,
		class _Pointer = _Tp*, class _Reference = _Tp&>
struct iterator {
        typedef _Category  iterator_category;
        typedef _Tp        value_type;
        typedef _Distance  difference_type;
        typedef _Pointer   pointer;
        typedef _Reference reference;
};
#endif /* __STL_USE_NAMESPACES */

traits机制

通过萃取机制,使得使用更加灵活。

iterator_traits 负责萃取迭代器的特性,__type_traits 负责萃取类型的特性。

iterator_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;
};
// native_pointer
template <class _Tp>
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 <class _Tp>
struct iterator_traits<const _Tp*> {
    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

获取迭代器类型

template <class _Iter>
inline typename iterator_traits<_Iter>::iterator_category
__iterator_category(const _Iter&)
{
    typedef typename iterator_traits<_Iter>::iterator_category _Category;
    return _Category();
}
template <class _Iter>
inline typename iterator_traits<_Iter>::iterator_category
iterator_category(const _Iter& __i) { return __iterator_category(__i); }

difference_type

获取迭代器间距离

template <class _Iter>
inline typename iterator_traits<_Iter>::difference_type*
__distance_type(const _Iter&)
{
    return static_cast<typename iterator_traits<_Iter>::difference_type*>(0);
}
template <class _Iter>
inline typename iterator_traits<_Iter>::difference_type*
distance_type(const _Iter& __i) { return __distance_type(__i); }
value_type

获取值类型

template <class _Iter>
inline typename iterator_traits<_Iter>::value_type*
__value_type(const _Iter&)
{
    return static_cast<typename iterator_traits<_Iter>::value_type*>(0);
}
template <class _Iter>
inline typename iterator_traits<_Iter>::value_type*
value_type(const _Iter& __i) { return __value_type(__i); }
__type_traits

提供了一种机制,允许针对不同的类型属性,在编译时期完成函数派送(function dispatch)

true/false
// class 没有任何成员,不会带来额外负担,却又能够标示真假。
struct __true_type {
};

struct __false_type {
};
基础traits定义
template <class _Tp>
struct __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 charsigned charunsigned charwchar_tshortunsigned shortintunsigned intlongunsigned longlong longunsigned long longfloatdoublelong doublechar*signed char*unsigned char*const char*const signed char*const unsigned char*template <class _Tp> _Tp*

以上类型默认__type_traits各成员均为true

除此之外,关于数组大小的限制,要求是int型,故也有_Is_integer类型萃取。

bool charsigned charunsigned charwchar_tshortunsigned shortintunsigned intlongunsigned longlong longunsigned long long

raw_storage_iterator

使标准算法可以将结果存储在未初始化的内存中。其相关基础定义如下

template <class _ForwardIterator, class _Tp>
class 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 <class _ForwardIterator, class _Tp>
inline output_iterator_tag
iterator_category(const raw_storage_iterator<_ForwardIterator, _Tp>&)
{
    return output_iterator_tag();
}

auto_ptr

前面说道 迭代器可以理解为智能指针,这里将介绍一下智能指针。

auto_ptr在c++11弃用,在c++17已移出

基础结构

进行封装后的原生指针。

template <class _Tp> 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 <class _Tp1> 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 <class _Tp1>
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()函数,故其只适用于含有该函数的容器。

template <class _Container>
class 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 <class _Container>
inline output_iterator_tag
iterator_category(const back_insert_iterator<_Container>&)
{
    return output_iterator_tag();
}

#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
//对外接口 传入的是支持push_back的容器 如 vector
template <class _Container>
inline back_insert_iterator<_Container> back_inserter(_Container& __x) {
    return back_insert_iterator<_Container>(__x);
}
front_insert_iterator

除了只能调用push_front()函数与back_insert_iterator完全一致。也提供对外接口front_inserter

insert_iterator

该适配器允许在任意位置插入元素。故其底层比头插、尾插的类模板多一个迭代器用来调整插入位置。

template <class _Container>
class 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 /* __SGI_STL_NO_ARROW_OPERATOR */
    _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 <class _BidirectionalIterator, class _Tp, class _Reference, class _Distance>
inline bidirectional_iterator_tag iterator_category(const reverse_bidirectional_iterator
                                                    <_BidirectionalIterator, _Tp, _Reference, _Distance>&) 
{
    return bidirectional_iterator_tag();
}
//value_type
template <class _BidirectionalIterator, class _Tp, class _Reference, class _Distance>
inline _Tp* value_type(const reverse_bidirectional_iterator
           <_BidirectionalIterator, _Tp,_Reference, _Distance>&)
{
    return (_Tp*) 0;
}
//distance_type
template <class _BidirectionalIterator, class _Tp, class _Reference, class _Distance>
inline _Distance* distance_type(const reverse_bidirectional_iterator
              <_BidirectionalIterator, _Tp,_Reference, _Distance>&)
{
    return (_Distance*) 0;
}
//运算符重载 ==
template <class _BiIter, class _Tp, class _Ref, class _Distance>
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 对象上,使之具备输入能力。

template <class _Tp, class _Dist>
class 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 <class _Tp, class _Dist>
inline input_iterator_tag  iterator_category(const istream_iterator<_Tp, _Dist>&)
{
    return input_iterator_tag();
}

ostream_iterator

将迭代器绑定到一个 ostream 对象上,使之具备输出能力。

template <class _Tp>
class 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;
    }
};
istreambuf_iterator

由于isteam_iterator采用operator>>来读取,而operator>>会忽略空格。因此考虑直接在缓冲区中读取。

template<class _CharT, class _Traits>
class istreambuf_iterator
    : public iterator<input_iterator_tag, _CharT,
typename _Traits::off_type, _CharT*, _CharT&>
{
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<class _CharT, class _Traits>
_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;
}
mutable关键字

const函数中,原则上不能够修改任意变量值。而如果变量是mutable关键字修饰时,则可以在const函数中进行修改。

mutable只能够用于一个类的非静态数据成员

ostreambuf_iterator

同理,将数据流出至缓冲区。无++运算符(返回自身)

template<class _CharT, class _Traits>
class ostreambuf_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
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;
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值