STL源码分析——迭代器(二)

2 篇文章 0 订阅
2 篇文章 0 订阅

迭代器适配器


reverse_iterator

首先,reverse_iterator包含一个迭代器数据成员,记为current
因为reverse_iteratoriterator指向的element是相同的,因此其构造函数,直接将参数赋值给current即可。

explicit reverse_iterator(Iter iter) : current(iter) {}

复制构造函数(模板)
reverse2的数据成员 赋值给 reverse1的数据成员,因此需要一个函数base()获取数据成员current

template<typename Iter2>
reverse_iterator(const reverse_iterator<Iter2>& rev_iter2) : current(rev_iter2.base()) {}

iterator_type base() const{
    return current;
}

deference
reverse_iterator保持指向的 element 位置不变,在deference时取向前一个元素的值。

reference operator*() const {
    iterator_type temp = current;
    return *(--temp);
}
pointer operator->() const{
    return learnSTL::addressof(operator*());
}

step
reverse_iteratoriterator是反向的,因此其++就相当于将current--

self_type& operator++() const{
    --current;
    return *this;
}
self_type& operator++(int) const{
    self_type temp(*this);
    ++current;
    return temp;
}

inserter

inserter 有 3 种,这里以 insert_iterator为例。
首先,inserter都有一个关联的Container,我们只保存期指针,对于insert_iterator,还需保存一个迭代器pos
output_iterator都不提供默认构造函数和复制构造函数。

explicit insert_iterator(Container& cont, typename Container::iterator iter) 
            : containerPtr(learnSTL::addressof(cont)),
              iter(iter) {}

对于output_iterator只有写动作iter = value才有效,转化为调用对应的insert方法

insert_iterator& operator=(typename Container::value_type& value){
    containerPtr->insert(iter, value);
    ++iter;
    return *this;
}
insert_iterator& operator=(typename Container::value_type&& value){
    containerPtr->insert(iter, std::move(value));
    ++iter;
    return *this;
}

其他操作都是无效的,直接返回本身即可。

insert_iterator& operator*()        { return *this; }
insert_iterator& operator++()       { return *this; }
insert_iterator  operator++(int)    { return *this; }

stream iterator

ostream iteratorstream相联系,在这里,我们可以把stream理解为一个char容器,参照insert迭代器适配器,我们也要保存一个stream指针,同时我们保存一个delim间隔符。
因为要保存一个stream指针,因此我们必须指定basic_istream的模板参数。

template<typename T, typename CharT = char, class Traits = std::char_traits<CharT> >
class ostream_iterator ...

其他操作和insert_iterator类似。

对于istream iterator。有几点比较特殊。一是每次读取的时候都要检查istream的状态,一旦不正常,则设置为end-of-stream;二是每次++操作,都会从istream中读取一个元素。三是只读属性导致*iter = value是不允许的,因此deference返回const属性

explicit istream_iterator(istream_type& is) : input_stream(learnSTL::addressof(is)){
    if (!(*input_stream >> value))
        input_stream = nullptr;
}
istream_iterator& operator++(){
    if (!(*input_stream >> value))
        input_stream = nullptr;
    return *this;
}

move_iterator

move_iterator就是对 iterator 做一层封装,使其产生右值语义,具体表现在deference时,返回的是右值,而不是左值。

还有一点注意的是,referencevalue_type&&,而不是iterator_traits<Iter>::reference

template<typename Iter>
class move_iterator{
public:
    typedef Iter                   iterator_type;

    typedef iterator_traits<Iter>::iterator_category  iterator_category;
    typedef iterator_traits<Iter>::value_type         value_type;
    typedef iterator_traits<Iter>::difference_type    difference_type;
    //typedef iterator_traits<Iter>::reference          reference;
    typedef value_type&&                              reference;
    typedef iterator_traits<Iter>::pointer            pointer;
    ...
    // rvalue must be const
    reference operator*() const{
        return static_cast<reference>(*__iter);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值