连续内存容器(contiguous-memory containers)(也叫做基于数组的容器(array-based containers))在一个或多个连续的内存块(动态分配的)存贮它们的元素,任一内存块容纳多于一个的容器元素。如果一个新元素被插入(inserted)或一个存在的元素被擦除(erased),在同一内存块中其它元素必须搬移为新元素提供空间或回收已擦除元素所占用的空间。这种移动会影响性能(见条款5和14)和异常安全(不久我们就会看到)。标准的连续内存容器(contiguous-memory containers)是vector,string和deque。非标准的rope也是一种连续内存容器(contiguous-memory containers)。
基于节点的容器(node-based containers)在每一个内存块(动态分配的)内只存贮一个单独元素。插入和擦除(erasure)只影响指向节点的指针,不影响节点本身的内容,所以执行插入或擦除操作时元素值不需要移动(意思是不需要移动内存块)。表示链表的容器如list和slist,以及所有的关联式容器都是基于节点(node-based)的。(它们一般都用平衡树实现。)非标准的散列容器(hashed containers)使用各种基于节点(node-based)的实现,请见条款25。
使用这种不太常用的(out of the way)术语,我们开始提出一些在选择容器时最相关的问题。在以下讨论中,我会忽略非类STL(non-STL-like)的容器(例如,arrays, bitsets等等),毕竟,这是一本关于STL的书。
n 你需要在容器中任意位置插入新元素的能力吗?如果是,你需要的是序列式容器,关联式容器没有这种功能。
n 你关心容器内的元素如何排序吗?如果不是,散列容器(hashed container)是一种可能的选择。否则,避免使用散列容器(hashed container)。
n 容器必须是标准C++的一部分吗?如果是,不要考虑散列容器(hashed containers),slist以及rope。
n 你需要哪种类型的迭代器呢?如果必须是random access iterators,从技术上讲,你只能使用vector, deque,和string,当然,你可能也想用rope。(关于rope更多的信息见条款50。)如果需要的是双向的迭代器,你必须避免使用slist(见条款50)以及散列容器(hashed container)的一般实现品(用普通方法实现的)(见条款25)。
n 当进行插入或擦除操作时,避免移动容器内已经存在的元素重要吗?如果是,那就请离连续内存容器远点(contiguous-memory containers)(见条款5)。
n 容器内的数据需要与C保持布局兼容(layout-compatible)吗?