最近有个开发需求,根据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的接口文档需要经常看看,避免造轮子。

deque 居然已经实现了 insert 接口的更多相关文章

  1. Spring中毒太深,离开Spring我居然连最基本的接口都不会写了

    前言 随着 Spring 的崛起以及其功能的完善,现在可能绝大部分项目的开发都是使用 Spring(全家桶) 来进行开发,Spring也确实和其名字一样,是开发者的春天,Spring 解放了程序员的双 ...

  2. Spring中毒太深,离开了Spring,我居然连最基本的接口都不会写了¯\_(ツ)_/¯

    前言 众所周知,Java必学的框架其中就是SSM,Spring已经融入了每个开发人员的生活,成为了不可或缺的一份子. 随着 Spring 的崛起以及其功能的完善,现在可能绝大部分项目的开发都是使用 S ...

  3. deque源码4(deque元素操作:pop_back、pop_front、clear、erase、insert)

    deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...

  4. java三篇博客转载 详解-vector,stack,queue,deque

    博客一:转载自http://shmilyaw-hotmail-com.iteye.com/blog/1825171 java stack的详细实现分析 简介 我们最常用的数据结构之一大概就是stack ...

  5. 在VMware 虚拟机中配置 windows2003系统的NLB负载均衡;0x800706D5错误的解决方法;没有接口可用于安装新的群集

    首先在VM里面 我装了3个2003的系统,  分别为 webservice01 ,webservice 02 , 以及   webview 这3台. 前面两台用于配置负载均衡,后面的webview就是 ...

  6. Java中的queue和deque对比详解

    队列(queue)简述 队列(queue)是一种常用的数据结构,可以将队列看做是一种特殊的线性表,该结构遵循的先进先出原则.Java中,LinkedList实现了Queue接口,因为LinkedLis ...

  7. JAVA集合接口及类

    各接口及类关系图 Iterable 所有集合的初始接口,实现该接口可进行foreach操作,只有一个iterator()方法,并返回iterator类型: Iterable在java.lang下,It ...

  8. Deque(队列)

    目录 Deque 概述 特点 常用方法 双向队列操作 ArrayDeque Deque 概述 一个线性 collection,支持在两端插入和移除元素.名称 deque 是"double e ...

  9. STL deque用法

    Deque 容器 deque容器是C++标准模版库(STL,Standard Template Library)中的部分内容.deque容器类与vector类似,支持随机访问和快速插入删除,它在容器中 ...

随机推荐

  1. number-of-boomerangs

    https://leetcode.com/problems/number-of-boomerangs/ package com.company; import java.util.*; class S ...

  2. 内存分配(c/c++)

    C++中内存分配          内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 1,栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的 ...

  3. Qt环境搭建(Qt Creator)

    简述 上一节中介绍了如何进行Qt和Visual Studio的下载安装,随后演示了如何将Qt集成到Visual Studio中,并完成了我们第一个Qt小程序-Hello World.下面主要讲解如何利 ...

  4. Chrome 快捷键使用

    窗口和标签页快捷方式 Ctrl+N 打开新窗口 按住 Ctrl‎ 键,然后点击链接 在新标签页中打开链接 按住 Shift 键,然后点击链接 在新窗口中打开链接 Alt+F4 关闭当前窗口 Ctrl+ ...

  5. 51nod1125 交换机器的最小代价

    跟做过的bzoj一道置换群的题几乎一样,只是数据范围大了点,那么就用map就好了... #include<cstdio> #include<cstring> #include& ...

  6. (转)IOS UITableView学习

    转自:http://www.cnblogs.com/smileEvday/archive/2012/06/28/tableView.html          作者:一片枫叶 看TableView的资 ...

  7. pg 匹配中文字符

    用到了正则表达式: 字段 ~'[\u4E00-\u9FA5]+$'; 注意:此表达式可能还不能取到最全的值.

  8. sql loader

    vi append.sh #!/bin/bash sqlldr userid=bm_weihu/itms_xianwan control=input2.ctl vi input2.ctl LOAD D ...

  9. web app 页面旋转整体样式问题

    $(window).bind("orientationchange", function (event) { if (event.orientation) { //portrait ...

  10. C++调试 输出数组内容和数组名

    #include <cstdio> using namespace std; //函数定义 #define printArr(arr,n,format) \ printf("%s ...