源码之前,了无秘密(一)——iterator adapter

阅读 iterator adapter 源码,我们将获悉以下结论背后的道理:

  • (1)如何鬼斧神工,将赋值变为插入,将前进变为后退了,绑定到任意装置上
  • (2)为什么 vector 不支持 front_inserter

一、Insert iterators:赋值变插入

赋值变插入的操作主要包括:

  • (1)专司尾端插入的 back_insert_iterator,

    back_insert_iterator 其实是模板类,通过 back_insert_iterator<Container>(coll)构造函数产生对象,
    因其接口使用极为不便,STL 提供了其相应的辅助函数(helper function):back_inserter(Container& coll)

template<class _Container>
    class back_insert_iterator
        : public _Outit
    {   // wrap pushes to back of container as output iterator
public:

    typedef back_insert_iterator<_Container> _Myt;
    typedef _Container container_type;
    typedef typename _Container::value_type _Valty;
    ...
    // 构造函数,
    explicit back_insert_iterator(_Container& _Cont)
    : container(_STD addressof(_Cont))
    {   // construct with container
    }
    ...
    // 维护的底层容器,通过构造函数进行赋值
    protected:
    _Container *container;  // pointer to container
    };
  • (2)专司头部插入的 front_insert_iterator,辅助函数 front_inserter

赋值变插入,可通过 front_inserter() 的源码以清晰地显示:

template<class _Container> inline
    front_insert_iterator<_Container> front_inserter(_Container& _Cont)
    {   // return front_insert_iterator
    return (_STD front_insert_iterator<_Container>(_Cont));
    }

template<class _Container>
class front_insert_iterator
    : public _Outit
{   
typedef front_insert_iterator<_Container> _Myt;
typedef _Container container_type;
typedef typename _Container::value_type _Valty;

    // 真正的赋值操作在这,它首先进行的是push_front
    // 自然从 赋值 变成了 插入
    // 显然 front_inserter 的参数必须是支持 push_front 成员方法的容器,
    // vector 容器就不符合要求
    _Myt& operator=(const _Valty& _Val)
    {   // push value into container
    container->push_front(_Val);
    return (*this);
    }
  • (3)任意位置插入的 insert_iterator,及其辅助函数 inserter

二、Reverse Iterators:前进变后退

所谓 reverse iterators,可以将一般迭代器的方向逆转,

  • (1)使原本应该前进的 operator++ 变成了后退操作,
  • (2)使原本应该后退的 operator– 变成了前进操做

这种倒转筋脉的性质运用在“从尾端开始进行”的算法上,有很大的方便性;

reverse_iterator rbegin() _NOEXCEPT
    {   // return iterator for beginning of reversed mutable sequence
    return (reverse_iterator(end()));
    }

reverse_iterator rend() _NOEXCEPT
    {   // return iterator for end of reversed mutable sequence
    return (reverse_iterator(begin()));
    }

由上述源码可知:rbegin()返回的是end() iterator,自然rend()实际上返回的是 begin()。

三、IOStream iterator:绑定到任意特殊装置上

所谓 IOStream iterators,可以将迭代器绑定到某个 iostream 对象身上。

  • (1)绑定到 istream 对象(std::cin)上,称为 istream_iterator,获得输入功能
  • (2)绑定到 ostream 对象(std::out)上,称为 ostream_iterator,获得输出功能;这种迭代器运用于屏幕输出,非常方便,
  • (3)以它为蓝图,稍加修改,便可适用于任何输出或输入装置上,
// 输出到屏幕
std::ostream_iterator<int> outite(std::cout, " ");
std::copy(coll.begin(), coll.end(), outite);

copy 函数关于第三个参数的要求,仍然是:解引用(*)和赋值(=);

我们查看 ostream_iterator 源码:

template<class _Ty,
    class _Elem = char,
    class _Traits = char_traits<_Elem> >
    class ostream_iterator
    {   // wrap _Ty inserts to output stream as output iterator
public:
    typedef _Elem char_type;
    typedef _Traits traits_type;
    typedef basic_ostream<_Elem, _Traits> ostream_type;

        ostream_iterator<_Ty, _Elem, _Traits>& operator=(const _Ty& _Val)
        {   // insert value into output stream, followed by delimiter
        *_Myostr << _Val;
        if (_Mydelim != 0)
            *_Myostr << _Mydelim;
        return (*this);
        }

    ostream_iterator<_Ty, _Elem, _Traits>& operator*()
        {   // pretend to return designated value
        return (*this);
        }
        ...

你可能感兴趣的:(源码之前,了无秘密(一)——iterator adapter)