STL略观——deque迭代器的一些关键行为

Posted Forever-Road

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL略观——deque迭代器的一些关键行为相关的知识,希望对你有一定的参考价值。

  由于迭代器内对各种指针都进行了重载操作,所以各种指针运算如++,--等都不能直观视之,最关键的是缓冲区边缘的相关操作,可能需要 _M_set_node 跳一个缓冲区:

    void _M_set_node(_Map_pointer __new_node)
    {
        _M_node = __new_node;
        _M_first = *__new_node;
        _M_last = _M_first + difference_type(_S_buffer_size());
    }

  以下几个运算子保证了迭代器的正常运行,其中还涉及到相互调用,也不难理解:

    reference operator*() const { return *_M_cur; }
    pointer operator->() const { return _M_cur; }

    difference_type operator-(const _Self& __x) const 
    {
        return difference_type(_S_buffer_size()) * (_M_node - __x._M_node - 1) +
        (_M_cur - _M_first) + (__x._M_last - __x._M_cur);
    }

    _Self& operator++() 
    {
        ++_M_cur;                        //切换至下一个元素
        if (_M_cur == _M_last)             //如果已达所有缓冲区的尾端
        {
            _M_set_node(_M_node + 1);   //切换至下一个节点对应的缓冲区的第一个元素
            _M_cur = _M_first;            
        }
        return *this; 
    }
    _Self operator++(int)                 //后置++
    {
        _Self __tmp = *this;
        ++*this;
        return __tmp;
    }

    _Self& operator--()                 
    {
        if (_M_cur == _M_first)            //如果已达所有缓冲区的尾端
        {
            _M_set_node(_M_node - 1);    //切换至下一个节点对应的缓冲区的第一个元素
            _M_cur = _M_last;
        }
        --_M_cur;                        //切换至下一个元素
        return *this;
    }
    _Self operator--(int)                 //后置--
    {
        _Self __tmp = *this;
        --*this;
        return __tmp;
    }
    //随机存取,迭代器跳跃 n 个距离
    _Self& operator+=(difference_type __n)
    {
        difference_type __offset = __n + (_M_cur - _M_first);
        if (__offset >= 0 && __offset < difference_type(_S_buffer_size()))
            //目标位置在同一缓冲区
            _M_cur += __n;
        else
        {    //目标位置不在同一缓冲区
            difference_type __node_offset =
            __offset > 0 ? __offset / difference_type(_S_buffer_size())
                   : -difference_type((-__offset - 1) / _S_buffer_size()) - 1;
            //节点切换
            _M_set_node(_M_node + __node_offset);
            _M_cur = _M_first + 
            //切换至正确元素
            (__offset - __node_offset * difference_type(_S_buffer_size()));
        }
        return *this;
    }

    _Self operator+(difference_type __n) const
    {
        _Self __tmp = *this;
        return __tmp += __n;
    }
    //调用+=完成-=
    _Self& operator-=(difference_type __n) { return *this += -__n; }

    _Self operator-(difference_type __n) const
    {
        _Self __tmp = *this;
        return __tmp -= __n;
    }

    reference operator[](difference_type __n) const { return *(*this + __n); }

    bool operator==(const _Self& __x) const { return _M_cur == __x._M_cur; }
    bool operator!=(const _Self& __x) const { return !(*this == __x); }
    bool operator<(const _Self& __x) const 
    {
        return (_M_node == __x._M_node) ? 
        (_M_cur < __x._M_cur) : (_M_node < __x._M_node);
    }
    bool operator>(const _Self& __x) const  { return __x < *this; }
    bool operator<=(const _Self& __x) const { return !(__x < *this); }
    bool operator>=(const _Self& __x) const { return !(*this < __x); }

    void _M_set_node(_Map_pointer __new_node)
    {
        _M_node = __new_node;
        _M_first = *__new_node;
        _M_last = _M_first + difference_type(_S_buffer_size());
    }

 

以上是关于STL略观——deque迭代器的一些关键行为的主要内容,如果未能解决你的问题,请参考以下文章

STL——容器(deque) 元素的存取&迭代器

STL 迭代器(iterator)详解

STL源代码剖析 容器 stl_deque.h

STL中的vector和list的迭代器引申的关于迭代器的总结

STL—queue和stack使用及源码剖析

c++ STL 迭代器失效问题