您的位置:首页 > Web前端

【笔记】第一条:慎重选择容器类型

2016-10-30 21:43 309 查看
一:容器类型:

1 标准STL序列容器:vector,string,deque,list

标准STL关联容器:set,multiset,map,multimap

非标准序列容器:slist,rope

非标准的关联容器:hash_set,hash_multiset,hash_map,hash_multimap

vector<char>作为string的替代

vector作为标准关联容器的替代

几种标准的非STL容器:数组,bitset,valarray,stack,queue,priority_queue

2 连续内存容器(基于数组的容器):vector,string,deque.(rope)

非连续内存容器(基于节点的容器):list,slist,所有标准的关联容器(通常实现方式是平衡树)。

3 选择:

是否需要在容器的任意位置插入新元素?是:序列容器

是否关心容器中的元素是排列的?不关心,则哈希容器是一可行方案;否则,避免之

选择的容器必须是标准C++的一部分?必须是,排除哈希容器、slist和rope

需要哪种类型的迭代器?如果必须是随机访问迭代器,则限定为vector,deque,string,(rope)。若使用双向迭代器,则避免slist及哈希容器的一个常见实现。

当发生元素的插入或删除操作时,避免移动容器中原来的元素是否很重要?如果是,就要避免连续内存的容器

容器中数据的布局是否需要和C兼容?如果需要兼容,就只能选择vector

元素的查找速度是否是关键的考虑因素?如果是,就要考虑哈希容器、排序的vector、和标准关联容器——或许这就是优先顺序。

如果容器内部使用了引用计数技术,是否介意?如果是,就避免使用string,因为许多string的实现都使用了引用计数。rope也需避免,因为权威的rope实现是基于引用计数的。当然,你需要某种表示字符串的方法,这是你可以考虑vector<char>

对插入和删除操作,你需要事务语义吗?也就是说,在插入和删除操作失败时,你需要回滚的能力吗?如果需要,你就要使用基于节点的容器。如果对多个元素的插入操作(即针对一个区间的形式——第5条)需要事务语义,则需要选择list,因为在标准容器中,只有list对uoge元素的插入操作提供了事务语义。对那些希望编写异常安全代码的程序员,事务语义显得尤为重要(使用连续内存的容器也可以获得事务语义,但要付出性能上的代价,而且代码也显得不那么直截了当。更多细节,参考Sutter的Exceptional
C++[8]中的17条)。

需要使迭代器、指针和引用变为无效的次数最少吗?如果是这样,就需要使用基于节点的容器,因为对这类容器的插入和删除操作从来不会使迭代器、指针和引用变为无效(除非它们指向一个你正在删除的元素)。而针对连续内存容器的插入和删除操作一般会使指向该容器的迭代器、指针和引用变为无效。

如果在容器上使用swap,使得迭代器、指针或引用变为无效了,你会在意吗?如果再有,那么你要避免使用string,因为string是STL中在swap过程中会导致迭代器、指针和引用变为无效的唯一容器。

如果序列容器的迭代器是随机访问类悉尼港,而且只要没有删除操作发生,且插入操作只发生在容器的末尾,则指向数据的指针和引用就不会变为无效,这样的容器是否对你有帮助?这是非常特殊的情形,但如果你面对的情绪正式如此,则deque是你所希望的容器(有意思的是,当插入操作仅仅在容器末尾发生时,deque的迭代器有可能会变为无效。deque是唯一的、迭代器可能会变为无效而指针和引用不会变为无效的STL标准容器)。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Effective STL 中文版 50