不会使迭代器(和指针)失效的容器

时间:2015-02-08 09:27:59

标签: c++ c++11 containers

我目前正在寻找提供一些插入(insert或push_back)的容器以及一些删除(erase,pop_back是不够的)方法,并且在调用这两种方法时不会使迭代器和指针无效。

更清楚的是,我想要一组元素,我可以在其中添加一个元素(我不关心在哪里),以及我可以删除任何元素的地方(所以我关心在哪里)。另外,我会有指向特定元素的外部指针,如果我在集合中添加或删除元素,我希望它们保持有效。

据我所知,有两个满足我需求的标准容器:setlist。但是,一般来说,我不喜欢将这种容器用于这种简单的需求。由于list内部涉及指针,并且不提供对其元素的随机访问,我认为这不是一个好的选择。 set可以随机访问其元素,但也涉及指针,随机访问本身不是在恒定时间内完成的。我认为setlist更好的解决方案,但我已经考虑了其他事情。

一个简单的向量怎么样,当一个元素被删除时,它不会试图保持元素连续?删除此容器中间的元素时,其位置将为空,并且不会发生任何其他情况。这样,就不会使迭代器或指针失效。此外,在添加元素时,容器会搜索空位置,如果没有这样的洞,则使用简单的push_back

显然,由于push_back可以使vector的迭代器无效,我会使用deque作为实现的基础。我还会使用某种堆栈来跟踪删除元素的漏洞。这样,添加,删除和访问元素将在恒定时间内完成,此外还满足我的无效请求。

然而,仍有一个问题:当迭代这个容器或只是通过索引访问元素时,我们需要考虑漏洞。这就是问题开始超越优势的地方。

因此我的问题是:您如何看待我对该容器的想法? 更重要的是,您会对我的原始问题使用什么,setlist或其他什么? 另外,如果您对上一个问题(迭代我的容器)有一个很好的干净解决方案,请随时给我看。

1 个答案:

答案 0 :(得分:3)

要求1:插入(插入或推回)和删除(擦除,而不仅仅是最后一个元素)

  • 合规候选人:dequeforward_listlistmapmulti_mapsetmultisetunordered_mapunordered_multimapunordered_setunordered_multisetvector

  • 取消候选人:array(无insertpush_back),queuepriority_queuestack(否{{ 1}},仅erase

要求2:在调用这两种方法时不会使迭代器或指针无效

  • 符合条件的候选人也满足要求1:popforward_listlistmapmulti_mapset
  • 擦除时消除:multiset(迭代器仅在擦除第一个元素时仍然有效)和deque(擦除开始后的所有元素)
  • 在插入时取消:vector(在大多数情况下),dequeueunordered_mapunordered_multimapunordered_set(如果增长需要rehash)和unordered_multiset(如果增长需要重新分配)

要求3:外部指针仍然有效

与要求2大致相同的结果。但vectorunordered_mapunordered_multimapunordered_set会满足此要求,因为对元素的引用仍然有效。

要求4:随机访问元素

  • 符合要求1和2的候选人:unordered_multisetmap
  • 几乎符合条件的候选人:multimapset没有随机访问权限,但可以使用成员multiset(O(logn))
  • 来满足它
  • 不符合:列表(尽管算法find()可以在O(n)中提供变通方法)。

回答问题1:哪个更好,find()set

这取决于您的其他要求。在一个集合中,每个值只能存储一次。如果您的元素都是唯一的,请选择该集。如果不是,您最好选择列表或多重集。

我不知道你要存储的元素,但搜索参数的整个元素是什么?还是有钥匙?在后一种情况下,你真的去寻找一张地图。

回答问题2:替代容器怎么样?

我不会为你的替代品选择deque。

如果您可以预见元素的最大数量,您可以简单地保留足够的容量以避免重新分配。 (满足要求1,3和4)。 如果你有一个"空元素"为了表示漏洞,你也可以满足要求2.在最坏的情况下,你可以选择一个矢量来分析你的元素和一个指示符是否有效。

如果这样的最大值无法确定,我宁愿选择list来证明其灵活性并满足您的所有要求。