• deque 居然已经实现了 insert 接口


    最近有个开发需求,根据server传递来的广告位来展示某条广告。

    但最终存储广告的数据结构是deque,里面存储的东西还是对象(stl 基于拷贝语义)。

    想了半天,在开头和结尾插入比较方便,在中间插入就有些困难了——因为是双端队列,思维惯性啊!

    另外一个问题deque中存储的是对象,这个涉及到覆盖和新的拷贝问题,如果对象很大(这就是现实),那会影响性能。

    网上

    但是产品需要摆在那边,没办法需要实现啊,只能在可能的情况下,尽量减少拷贝。

    于是想到如果插入位置在deque的前半部分,就对deque的前半部分进行操作(pop_front等),如果在deque的后半部分,

    就在deque的后半部分(push_back())进行操作。

    实现的过程中,有些接口忘了,去cppreference.com 上去查deque的接口,发现deque有insert接口——当时就崩溃了,有木有!!!

    http://en.cppreference.com/w/cpp/container/deque/insert

    iterator insert( iterator pos, const T& value );

    于是直接调用接口就好了,STL的实现比直接造的轮子好!!!!

    但这个不是结束,为什么deque会提供insert接口,它怎么实现的,是否会避免一些数据的拷贝?带着这个问题,我查看了下4.1.2的源码。

    template <typename _Tp, typename _Alloc>
        typename deque<_Tp, _Alloc>::iterator
        deque<_Tp, _Alloc>::
        insert(iterator position, const value_type& __x)
        {
          if (position._M_cur == this->_M_impl._M_start._M_cur)
        {
          push_front(__x);
          return this->_M_impl._M_start;
        }
          else if (position._M_cur == this->_M_impl._M_finish._M_cur)
        {
          push_back(__x);
          iterator __tmp = this->_M_impl._M_finish;
          --__tmp;
          return __tmp;
        }
          else
            return _M_insert_aux(position, __x);
        }

    可以看到这个函数,先判断了pos的位置,如果在前面插入,则调用push_front,如果在末尾插入,则调用push_back。

    我们关注的在中间插入,走向了_M_insert_aux函数。

    template <typename _Tp, typename _Alloc>
        typename deque<_Tp, _Alloc>::iterator
        deque<_Tp, _Alloc>::
        _M_insert_aux(iterator __pos, const value_type& __x)
        {
          difference_type __index = __pos - this->_M_impl._M_start;
          value_type __x_copy = __x; // XXX copy
          if (static_cast<size_type>(__index) < size() / 2)
        {
          push_front(front());
          iterator __front1 = this->_M_impl._M_start;
          ++__front1;
          iterator __front2 = __front1;
          ++__front2;
          __pos = this->_M_impl._M_start + __index;
          iterator __pos1 = __pos;
          ++__pos1;
          std::copy(__front2, __pos1, __front1);
        }
    
    。。。。。

    这个的实现,与我们当时的设想很类似,即看插入的位置与中间元素的关系,如果在前面,则push_front,否则push_back

    总结1. STL的人很有爱(某人说的),这个接口都提供了,而且实现效率还可以。

    2. STL的接口文档需要经常看看,避免造轮子。

  • 相关阅读:
    写在开始前表单数据校验
    Redis之时间轮机制(五)
    Reids高性能原理(六)
    redis持久化之RDB (七)
    Redis的使用(二)
    redisson之分布式锁实现原理(三)
    redis主从复制(九)
    Redis的内存淘汰策略(八)
    Redis之Lua的应用(四)
    《长安的荔枝》读书笔记
  • 原文地址:https://www.cnblogs.com/westfly/p/4230946.html
Copyright © 2020-2023  润新知