为什么std :: vector比std :: deque更受欢迎?

可能重复:
为什么我更喜欢使用vector来检测

我很好奇为什么std::vectorstd::deque更受欢迎。 Deque在查找方面几乎同样高效,插入效率更高(没有vector :: reserve),并允许在前面插入/删除。

香草萨特曾经build议, 如果你想使用vector,只喜欢德克 (我是释义)。 然而,在最近的写作现代C + +的谈话,他再次强烈build议思考作为默认容器的std::vector 。 根据前面联系的GOTW ,甚至标准也有类似的措辞。

这种差距有什么原因吗? 这只是vector更简单,更知名,还是有技术上的原因? 或者是vector只是一个更酷的名字..?

我不能为别人说话,但我可以为我自己。

当我第一次读到std::deque ,我觉得它足够酷了一段时间,我不仅把它当作默认的容器,而且几乎是我使用的唯一的容器。

然后有人问到为什么,我详细阐述了它的优点,以及为什么它是几乎所有东西中使用的最好的容器,以及它如何比std::vector多得多。

幸运的是,那个质疑我的决定的人很有说服力,我做了一些testing。 testing表明,几乎在所有情况下, std::deque都比std::vector慢 – 通常是一个相当大的因素(例如2)。 事实上,在我使用std::deque编写的代码中,只需将std::dequereplace为std::vector就可以在除less数情况之外的所有情况下加速。

在这之后的几个例子中,我使用了std::deque ,但是绝对不要把它作为默认值。 简单的事实是,在大多数情况下,在通常的实现中,它明显比std::vector慢。

但是,我应该补充一点,我相当肯定的是,通过正确的实现,在几乎所有情况下,它几乎可以和std::vector相当。 大多数情况下,从一个渐近的观点来看,这个表示无疑是非常好的,但是在现实世界中却不是如此奇妙(对于很多目的而言)。

std::vector非常好理解,简单并且与C兼容(无论是在内存布局方面,还是在使用指针作为迭代器方面)。

对于一些操作,它也比std::deque更高效。 通过索引访问元素就是一个例子。

对于一个给定的任务,使用最简单的容器来完成工作是很有意义的。 在很多情况下,最简单的容器是std::vector

由于一个简单的原因,人们在std :: deque上使用std :: vector。 它们与很多C库接口,它们具有需要指向连续存储的参数的函数 ,而std :: deque不能(不能)保证。

另一个原因是当你根据std :: deque构build代码,并且你的需求改变了,所以你必须支持连续的访问,你将会有一些重构。

我不得不提到,有些图书馆的作者声称创build了更高效的vector实现,以便在容量增加时克服效率低下的问题。

std::deque的结构稍微复杂一些,这使得天真的迭代比std::vector要贵一些。 插入std::vector与重新分配往往不是大问题,特别是使用reserve()和只附加到结束。 此外,更容易理解std::vector无效规则,尽pipe它实际上是std::deque一个优点,即当只在两端插入/删除时,对象仍然保持放置状态(注意std::deque迭代器在每次插入时都会失效,独立于插入发生的地方)。 std:vector另一个std:vector是可以保证这些值在内存中是连续的,从而减less了内存分配。

我想,我会build议使用std::dequealgorithm一直优化使用分段序列(我不知道任何标准的C ++库做这种优化)和用户访问序列一致使用algorithm(据我可以告诉,只有极less数用户认为使用algorithm的选项)。 否则,我会怀疑std::deque只有在利用其特定属性(例如,对象保持放置并且可以在最后插入/删除)的情况下才是性能方面更好的select。 尽pipe如此,还是值得介绍两种方法。

除了std::vector是最常见的容器类之外,它还比std::deque有几个优点,即:

  • 一个典型的std::deque需要一个额外的间接访问elments不像std::vector
  • std::deque情况下,迭代器必须是智能指针,而不是指向std::vector指针。
  • std::vector元素保证是连续的,因此它与以数组为参数的c样式函数兼容。
  • std::deque不支持控制容量和重新分配的时刻。

特别是最后一点值得注意。