在哪种情况下我使用特定的STL容器?

Dan*_*oof 179 c++ stl container-data-type

我一直在阅读关于C++的书中的STL容器,特别是关于STL及其容器的部分.现在我明白了每一个都有自己的特定属性,而且我已经接近记住了所有这些...但我还没有掌握的是在哪种情况下使用它们.

解释是什么?示例代码是更受欢迎的.

zda*_*dan 324

这个备忘单提供了不同容器的非常好的总结.

请参阅底部的流程图,作为在不同使用场景中使用的指南:

http://linuxsoftware.co.nz/containerchoice.png

David Moore创建并获得CC BY-SA 3.0许可

  • 这个流程图是金色的,我希望我在c#中有类似的东西 (14认同)
  • 有谁有更新的链接?链接坏了 (5认同)
  • 起点必须是'vector`而不是空.http://stackoverflow.com/questions/10699265/how-can-i-efficiently-select-a-standard-library-container-in-c11 (3认同)
  • 现在,您有`unordered_map`和`unordered_set`(及其多变体),它们不在流程图中,但当您不关心顺序但需要按键查找元素时是不错的选择。他们的查找通常是O(1)而不是O(log n)。 (3认同)
  • 更新的链接:[C ++容器备忘单](http://homepages.e3.net.nz/~djm/cppcontainers.html)。 (2认同)
  • @ shuttle87不仅大小永远不会变化,更重要的是大小是在编译时决定的,永远不会变化. (2认同)
  • 我不认为“需要在中间插入/删除”自动意味着“列表”。在大多数情况下,使用“向量”*仍然*会更快。 (2认同)

Mik*_*son 182

这是一个灵感来自David Moore的版本(见上文)的流程图,我使用新标准(C++ 11)创建了最新版本(主要是).这只是我个人对它的看法,这不是无可争议的,但我认为这对这个讨论很有价值:

在此输入图像描述

  • 你能提供原件吗?这是一张很棒的图表.也许坚持在博客或GitHub? (4认同)
  • @STALKER持久位置意味着如果你有一个容器中的元素的指针或迭代器,那么无论你在容器中添加或删除什么,该指针或迭代器都将保持有效(并指向同一个元素)(只要它不是问题的元素). (3认同)

Dav*_*ley 39

简单回答:std::vector除非你有其他原因,否则请用于所有事情.

当你发现一个你正在思考的情况时,"哎呀,std::vector因为X而在这里效果不好",那就去X吧.

  • @Black Point是,即使理论上运行速度较慢的操作,矢量通常也会更快. (13认同)
  • 嗯......我认为人们过度使用矢量.原因是,"不起作用"的情况不会轻易发生 - 因此人们坚持使用最常用的容器并滥用它来存储列表,队列,......在我的意见中 - 与流程图相匹配 - 一个人应该根据预期用途选择容器,而不是应用"一个似乎适合所有人". (9认同)
  • @Vardhan `std::remove_if` 几乎总是优于“迭代期间删除”方法。 (2认同)

Mar*_*sky 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).

  • 列表 - "你不能顺序访问一个元素." - 我认为你的意思是你不能随机访问或直接索引元素.... (3认同)

Ebr*_*him 7

我重新设计了流程图以获得3个属性:

  1. 我认为STL容器分为两大类.基本容器和利用基本容器来实现策略.
  2. 首先,流程图应该将决策过程分为我们应该决定的主要情况,然后详细说明每个案例.
  3. 一些扩展容器可以选择不同的基本容器作为其内部容器.流程图应考虑可以使用每个基本容器的情况.

流程图: 在此输入图像描述

此链接提供了更多信息.


Jon*_*ely 5

只简单地提到迄今很重要的一点是,如果你需要连续的存储器(如C数组给出),则只能使用vectorarraystring

array如果在编译时已知大小,则使用此方法。

使用string,如果你只需要使用字符类型的工作,需要一个字符串,而不是只是一个通用的容器。

使用vector在所有其他情况下(vector应该是在大多数情况下,默认选择容器的反正)。

使用这三种方法,您都可以使用data()成员函数获取指向容器第一个元素的指针。