我很好奇为什么std::vector
比std::deque
更受欢迎。 Deque几乎和查找一样有效,插入更有效(没有vector :: reserve),允许在前面插入/删除。
Herb Sutter曾推荐过if you want to use vector, just prefer deque(我在解读)。然而,在最近关于Writing Modern C++的讨论中,他再次强烈建议将std::vector
视为默认容器。根据我之前链接的GOTW,即使标准也有类似的措辞。
这种差异是否有原因?只是vector
更简单,更熟知,还是有技术原因?或者是vector
只是一个更酷的名字..?
答案 0 :(得分:56)
我不能为别人说话,但我可以为自己说话。
当我第一次阅读关于std::deque
的内容时,我觉得很酷,有一段时间,我不仅把它当作默认容器,而且几乎只用了我使用的 容器
然后有人问起为什么,我详细阐述了它的优点,以及为什么它是几乎所有东西都使用的最佳容器,以及它比std::vector
更加通用。
幸运的是,那个质疑我的决定的人很有说服力,我做了一些测试。测试显示,几乎在每种情况下,std::deque
都比std::vector
慢 - 通常是一个重要因素(例如,大约2)。事实上,在我使用std::deque
编写的代码中,只需将std::deque
替换为std::vector
,除了少数情况外,其他所有代码都会加速。
从那时起,我在少数情况下使用了std::deque
,但绝对不再将其视为默认值。简单的事实是,在通常的实现中,对于大多数目的而言,它明显慢于std::vector
。
std::vector
。大多数人使用从渐近的观点来看无疑是伟大的表现形式,但在现实世界中并没有如此奇妙地(出于许多目的)。
答案 1 :(得分:14)
std::vector
非常容易理解,简单且与C兼容(在内存布局和使用指针作为迭代器方面)。
对于某些操作,它也比std::deque
更有效。按索引访问元素就是一个例子。
对于给定的任务,使用最简单的容器来完成工作是有意义的。在许多情况下,最简单的容器是std::vector
。
答案 2 :(得分:5)
除std::vector
是最常见的容器类外,它还具有优于std::deque
的几个优点,即:
std::deque
的情况不同,典型的std::vector
需要额外的间接访问权限。 std::deque
的情况下的迭代器必须是智能指针,而不是std::vector
的指针。std::vector
的元素保证是连续的,因此它与以数组作为参数的c风格函数兼容。std::deque
不提供任何支持来控制容量和重新分配的时刻。特别是,最后一点值得注意。
答案 3 :(得分:5)
人们在std :: deque上使用std :: vector的原因很简单。它们与许多C库接口,并且它们具有functions参数,这些参数需要指向连续存储的指针,而std :: deque不能(不能)保证。
另一个原因是当您根据std :: deque构建代码并且您的需求发生变化以便您必须支持连续访问时,您将需要进行一些重构。
答案 4 :(得分:5)
std::deque
的结构有点复杂,使得天真迭代比std::vector
贵得多。插入std::vector
及其重新分配往往不是大问题,尤其是在使用reserve()
并且仅附加到结尾时。此外,更容易理解std::vector
的失效规则,尽管std::deque
实际上有一个优势,即只在任一端插入/删除时对象保持不变(请注意std::deque
迭代器无效在每次插入时,与插入发生的位置无关)。 std:vector
的另一个好处是保证值在内存中是连续的,从而减少内存分配。
我想,我建议使用std::deque
算法进行一致优化以使用分段序列(我不知道任何标准C ++库进行此优化)并且用户使用算法一致地访问序列(目前为止)据我所知,只有一小部分用户考虑使用算法的选项。否则,我怀疑只有当你利用它的特定属性时std::deque
才是性能方面更好的选择(例如,对象保持不变并且你可以在最后插入/删除)。不过,值得描述两种选择。