我一直在阅读关于C ++的书中的STL容器,特别是关于STL及其容器的部分。现在我明白每一个人都有自己特定的属性,而且我已经接近记住了所有这些属性......但我还没有掌握的是在哪种情况下使用它们。
解释是什么?示例代码是首选。
答案 0 :(得分:312)
答案 1 :(得分:173)
这是一个灵感来自David Moore的版本(见上文)的流程图,我使用新标准(C ++ 11)创建了最新版本(主要是)。这只是我个人的看法,它不是无可争议的,但我认为这对这次讨论很有价值:
答案 2 :(得分:38)
简单回答:除非您有其他原因,否则请使用std::vector
。
当你发现一个你正在思考的案例时,“Gee,std::vector
因为X而在这里效果不好”,请以X为基础。
答案 3 :(得分:10)
看看Scott Meyers的Effective STL。它擅长解释如何使用STL。
如果你想存储一个确定/未确定数量的对象而你永远不会删除任何对象,那么你想要的是一个向量。它是C数组的默认替换,它可以像一个一样工作,但不会溢出。您也可以使用reserve()预先设置其大小。
如果你想存储不确定数量的对象,但是你要添加它们并删除它们,那么你可能想要一个列表......因为你可以删除一个元素而不移动任何后续元素 - 与vector不同。但是,它需要比矢量更多的内存,并且您无法顺序访问元素。
如果你想获取一堆元素并只找到这些元素的唯一值,那么将它们全部读入一个集合就可以了,它也会为你排序。
如果你有很多键值对,并且你想按键对它们进行排序,那么地图很有用......但是每个键只能保存一个值。如果每个键需要多个值,则可以在地图中使用矢量/列表作为值,或使用多图。
它不在STL中,但它在STL的TR1更新中:如果你有很多键值对,你将按键查找,而你不关心它们的顺序,您可能想要使用哈希 - 这是tr1 :: unordered_map。我在Visual C ++ 7.1中使用它,它被称为stdext :: hash_map。它有一个O(1)的查找,而不是查找地图的O(log n)。
答案 4 :(得分:7)
我重新设计了流程图,使其具有3个属性:
this link中提供了更多信息。
答案 5 :(得分:5)
到目前为止只是简单提到的重要一点是,如果你需要连续的内存(比如C数组给出),那么你只能使用vector
,array
或string
如果在编译时已知大小,请使用array
。
如果您只需要使用字符类型并且需要字符串而不仅仅是通用容器,请使用string
。
在所有其他情况下使用vector
(无论如何,vector
应该是容器的默认选择。)
使用所有这三个,您可以使用data()
成员函数来获取指向容器第一个元素的指针。
答案 6 :(得分:3)
这完全取决于您要存储的内容以及您要对容器执行的操作。以下是我最常使用的容器类的一些(非常详尽的)示例:
vector
:紧凑的布局,每个包含的对象很少或没有内存开销。高效迭代。追加,插入和擦除可能很昂贵,特别是对于复杂的对象。通过索引找到包含对象的便宜,例如myVector [10]。使用在C中使用数组的地方。好的地方有很多简单的对象(例如int)。在向容器添加大量对象之前,请不要忘记使用reserve()
。
list
:每个包含对象的内存开销很小。高效迭代。追加,插入和擦除都很便宜。使用在C中使用链接列表的位置。
set
(和multiset
):每个包含对象的重要内存开销。在需要的地方使用,以便快速找到该容器是否包含给定对象,还是有效地合并容器。
map
(和multimap
):每个包含对象的重要内存开销。使用您想要存储键值对的位置并快速按键查找值。
zdan建议的cheat sheet流程图提供了更详尽的指南。
答案 7 :(得分:2)
我学到的一个教训是:尝试将它包装在一个类中,因为在一天之内更改容器类型会产生很大的意外。
class CollectionOfFoo {
Collection<Foo*> foos;
.. delegate methods specifically
}
预先花费不多,并且当你想要在这个结构上操作x的时候想要破解时节省调试时间。
为工作选择完美的数据结构:
每个数据结构都提供了一些操作,这些操作可能会有不同的时间复杂度:
O(1),O(lg N),O(N)等
你必须最好地猜测一下最常做的操作,并使用一个具有O(1)操作的数据结构。
简单,不是吗( - :
答案 8 :(得分:1)
我扩展了Mikael Persson's精彩的流程图。我添加了一些容器类别,数组容器和一些注释。如果您喜欢自己的副本,here就是Google绘图。谢谢,Mikael做了基础工作! C++ Container Picker
答案 9 :(得分:1)
我在另一个问题中回答了这个问题,该问题被标记为该问题的重复。但是我觉得很高兴参考一些有关选择标准容器的决定的好文章。
正如@David Thornley回答的那样,如果没有其他特殊需要,std :: vector是必经之路。这是C ++的创建者Bjarne Stroustrup在2014年博客中提出的建议。
这是文章的链接 https://isocpp.org/blog/2014/06/stroustrup-lists
并引用其中的内容
是的,我的建议是默认使用std :: vector。
在评论中,用户@NathanOliver还提供了另一个不错的博客,该博客具有更具体的度量。 https://baptiste-wicht.com/posts/2012/12/cpp-benchmark-vector-list-deque.html。