std::list
在一些极端情况下很有用。
但是,C++ 顺序容器的一般规则是“如果您的算法兼容,请使用std::vector
. 如果您的算法不兼容,请修改您的算法以便您可以使用std::vector
.”
存在例外情况,这里尝试详尽列出std::list
更好选择的原因:
当您需要 (A) 插入容器中间和 (B) 您需要内存中的每个对象位置保持稳定时。要求 (B) 通常可以通过使用由指向元素的指针组成的不稳定容器来删除,因此这不是使用std::list
.
当您需要 (A) 在容器中间插入或删除 (B) 时,数量级比您需要迭代容器的次数多。这也是一个极端的极端情况:为了从 a 中找到要删除的元素list
,您通常需要迭代!
这导致
您需要 (A) 在容器中间插入或删除,并且 (B) 让所有其他元素的迭代器保持有效。这最终成为案例 1 和案例 2 的隐藏要求:当您没有持久迭代器时,删除或插入的频率比迭代的频率高,并且迭代器和对象的稳定性高度相关。
最后一个案例,是拼接的案例曾经是使用的一个理由std::list
。
回到 C++03,所有版本的std::list::splice
(理论上)都可以在 O(1) 时间内完成。然而,极其有效的形式splice
要求size
是 O(n) 操作。C++11 要求size
在list
O(1) 上,因此splice
的极端效率仅限于“拼接整个其他列表”和“自拼接子列表”的情况。在单个元素拼接的情况下,这只是插入和删除。在子范围拼接的情况下,代码现在必须访问拼接中的每个节点来计算它们以保持size
O(1)(自拼接除外)。
因此,如果您只进行整体list
拼接或自列表子范围splice
,list
则可以比其他非列表容器更快地完成这些操作。