STL

容器 --- 迭代器 --- 函数对象 --- 泛型算法 --- 适配器(容器、算法)

《Effective STL》

http://www.cplusplus.com/reference


输出格式:

std::boolalpha  布尔类型



一、标准序列容器:vector、string、deque和list

1. vector

对vector操作,会有“复制”动作,也可能有“分割问题”,因此可以考虑“建立指针的容器而不是对象的容器”。

保证内存连续 --- 与数组类似;

range (1)
template <class InputIterator>
  void assign (InputIterator first, InputIterator last);      ----- 区间赋值,所有容器都支持
fill (2)
void assign (size_type n, const value_type& val);

single element (1)
iterator insert (iterator position, const value_type& val);
fill (2)
    void insert (iterator position, size_type n, const value_type& val);
range (3)
template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last); --- 区间插入

2. vector<bool>

typedef vector<bool, alloc> bit_vector;

采用压缩存储方式,一个字节存储8个bool值;--- 不符合标准,所以:第一,它不是一个STL容器。第二,它并不容纳bool。

vector<bool>做为说明STL可以支持包含通过代理访问元素的容器的演示。--- 代理模式

最好不要使用它;而deque<bool>和bitset是基本能满足你对vector<bool>提供的性能的需要的替代数据结构;


3. deque:

与vector相比:

  • deque提供了几乎所有vector所提供的(不支持reserve和capacity);
  • 可以在头进行操作;
  • 与string一样,不保证内存连续;只有vector保证内存连续;

4. 构造函数:

deque,vector,list

default (1)

explicit list (const allocator_type& alloc = allocator_type());

fill (2)

explicit list (size_type n, const value_type& val = value_type(),

                const allocator_type& alloc = allocator_type());

range (3)

template <class InputIterator>

  list (InputIterator first, InputIterator last,

         const allocator_type& alloc = allocator_type());            ---------- 区间构造函数

copy (4)

list (const list& x);

5. 注意remove和erase的区别

void remove (const value_type& val);   ------ 除list容器外,其他容器的remove并不能真正删除元素,容器大小未变。
iterator erase (iterator position);
iterator erase (iterator first, iterator last);   --------- 区间删除




二、标准关联容器:set、multiset、map和multimap

1、map:

single element (1)
pair<iterator,bool> insert (const value_type& val); 
--- 第二个返回bool为操作结果,如果已经存在,插入失败,返回false。
with hint (2)
iterator insert (iterator position, const value_type& val);
range (3)
template <class InputIterator>
  void insert (InputIterator first, InputIterator last); ------- 这个和其他容器不同,不需要指定位置。


如果已经存在,则返回存在element的iterator。

插入更新的N种方式:

std::map<char,int> mymap;
mymap.insert ( std::pair<char,int>('a',100) );
mymap.insert ( make_pair('a',100) );
mymap.insert ( std::map<char,int>::vaule_type('a',100) );     -------- 插入时insert效率高!
mymap['a'] = 100;  -------- 更新时效率高!

iterator lower_bound (const key_type& k);
const_iterator lower_bound (const key_type& k) const;

lower_bound --- 返回第一个大于等于key的迭代器;
upper_bound --- 返回第一个大于key的迭代器;如果没有等于key的元素,则这两个成员函数返回相同迭代器!



2、构造函数:

1、map:

map\set:

empty (1)

explicit map (const key_compare& comp = key_compare(),

              const allocator_type& alloc = allocator_type());

range (2)

template <class InputIterator>

  map (InputIterator first, InputIterator last,

       const key_compare& comp = key_compare(),

       const allocator_type& alloc = allocator_type()); --------- 区间构造函数

copy (3)

map (const map& x);


三、标准容器适配器:stack、queue、priority_queue。缺少迭代器的支持

1. queue:FIFO

template < class T, class Container = deque<T> > class queue;

要求容器支持front()、back()、push_back()、pop_front()操作;只有dqueue和list支持。

queue<int,list<int> > third; // empty queue with list as underlying container

queue<int> first;            // empty queue


2. priority_queue

template < class T, class Container = vector<T>,

           class Compare = less<typename Container::value_type> > class priority_queue;

要求容器支持front()、push_back()、pop_back(),只有vector和dqueue支持,默认为vector。

本质采用heap实现。


3. stack:LIFO

template < class T, class Container = deque<T> > class stack;

要求容器支持back()、push_back()、pop_back()操作;只有vector、dqueue和list支持。


四、非标准序列容器slist和rope。slist是一个单向链表(C++11最终定义为forward_list),rope本质上是一个重型字符串.

forward_list、list同顺序容器相比最大缺陷就是无法快速定位,不支持operator []。


五、非标准关联容器hash_set、hash_multiset、hash_map和hash_multimap. C++11最终定义为unordered_set等。

                  不同版本可能实现不同,高级使用请看code。

六、vector<char>可以作为string的替代品。
七、vector作为标准关联容器的替代品。
八、C++标准,非STL容器

1. bitset

bitset不是一个STL容器,但它是C++标准库的一部分。与STL容器不同,它的大小(元素数量)在编译期固定,因此它不支持插入和删除元素。

template < size_t N > class bitset;

按位存储;

内部实现采用整数数组存储bitset。


2. valarray

template <class _Tp> class valarray;

内部实现采用_Tp类型的指针数组。

可以resize,不过resize后原有数据全部丢失。





绑定器:函数bind1st和bind2nd


连续内存容器(也叫做基于数组的容器)在一个或多个(动态分配)的内存块中保存它们的元素。标准的连续内存容器是vector、string和deque。非标准的rope也是连续内存容器。

  • 你需要“可以在容器的任意位置插入一个新元素”的能力吗?如果是,你需要序列容器,关联容器做不到。
  • 你关心元素在容器中的顺序吗?如果不,散列容器就是可行的选择。否则,你要避免使用散列容器。
  • 必须使用标准C++中的容器吗?如果是,就可以除去散列容器、slist和rope。
  • 你需要哪一类迭代器?如果必须是随机访问迭代器,在技术上你就只能限于vector、deque和string,但你也可能会考虑rope(关于rope的更多信息在条款50)。如果需要双向迭代器,你就用不了slist(参见条款50)和散列容器的一般实现(参见条款25)。
  • 当插入或者删除数据时,是否非常在意容器内现有元素的移动?如果是,你就必须放弃连续内存容器(参见条款5)。
  • 容器中的数据的内存布局需要兼容C吗?如果是,你就只能用vector(参见条款16)。
  • 查找速度很重要吗?如果是,你就应该看看散列容器(参见条款25),排序的vector(参见条款23)和标准的关联容器——大概是这个顺序。
  • 你介意如果容器的底层使用了引用计数吗?如果是,你就得避开string,因为很多string的实现是用引用计数(参见条款13)。你也不能用rope,因为权威的rope实现是基于引用计数的(参见条款50)。于是你得重新审核你的string,你可以考虑使用vector<char>。
  • 你需要插入和删除的事务性语义吗?也就是说,你需要有可靠地回退插入和删除的能力吗?如果是,你就需要使用基于节点的容器。如果你需要多元素插入(比如,以范围的方式——参见条款5)的事务性语义,你就应该选择list,因为list是唯一提供多元素插入事务性语义的标准容器。事务性语义对于有兴趣写异常安全代码的程序员来说非常重要。(事务性语义也可以在连续内存容器上实现,但会有一个性能开销,而且代码不那么直观。要了解这方面的知识,请参考Sutter的《Exceptional C++》的条款17[8]。)
  • 你要把迭代器、指针和引用的失效次数减到最少吗?如果是,你就应该使用基于节点的容器,因为在这些容器上进行插入和删除不会使迭代器、指针和引用失效(除非它们指向你删除的元素)。一般来说,在连续内存容器上插入和删除会使所有指向容器的迭代器、指针和引用失效。
  • 你需要具有有以下特性的序列容器吗:1)可以使用随机访问迭代器;2)只要没有删除而且插入只发生在容器结尾,指针和引用的数据就不会失效?这个一个非常特殊的情况,但如果你遇到这种情况,deque就是你梦想的容器。(有趣的是,当插入只在容器结尾时,deque的迭代器也可能会失效,deque是唯一一个“在迭代器失效时不会使它的指针和引用失效”的标准STL容器。)


1、map:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值