【问题标题】:Keeping vector of iterators of the data保持数据迭代器的向量
【发布时间】:2016-02-14 00:55:45
【问题描述】:

我有一个功能:

void get_good_items(const std::vector<T>& data,std::vector<XXX>& good_items);

此函数应检查所有数据并找到满足条件的项目并在 good_items 中返回它们在哪里。

什么是最好的而不是std::vector&lt;XXX&gt;?

  1. std::vector&lt;size_t&gt; 包含所有好的索引。
  2. std::vector&lt;T*&gt; 包含指向项目的指针。
  3. std::vector&lt;std::vector&lt;T&gt;::iterator&gt; 包含项目的迭代器。
  4. 其他??

编辑:

我将如何处理good_items? 很多事情......其中之一是从向量中删除它们并将它们保存在其他地方。以后可能会有别的东西

编辑 2:

对我来说最重要的一个是如何根据good_items 的结构快速访问data 中的项目?

编辑 3:

我刚刚意识到我的想法是错误的。将原始指针(或智能)保留为向量的项不是更好,这样我就可以保留向量的真实值(即指针)并且我不怕繁重的复制,因为它们只是指针?

【问题讨论】:

  • 你会只在调用函数中使用结果,还是尝试存储它以便再次使用它(在向量可能已经改变之后)?任何其他代码(可能在不同的线程中)是否会修改 get_good_items 和您使用结果之间的向量?
  • 现在让我们不用担心线程安全
  • 如果数据向量被修改(从其中删除元素,将其从一个内存范围移动到另一个内存范围等),引用将中断。在这种情况下,您可以将好项目从数据复制到 good_items。如果不修改数据向量,您可以轻松地存储指向项目的指针(因此 2 将是可行的方法,因为 omho 更容易处理并且更具可读性)。
  • @rbaleksandar 如果在我想解雇 good_items 之前没有发生任何变化?
  • 如果data 使用存储在good_items 中的引用保留在内存中的位置,则从data 删除项目不会有问题。但是,如果您将data 移动到其他位置内存或例如通过直接访问data 而不是通过存储在good_items 中的引用来删除项目,您将获得一个或多个损坏的引用,因为存储在good_items 中的指针将指向内存中不再包含的位置适当的内容(因为您已经删除了该项目)。这通常适用于使用指针时,而不仅适用于您的情况

标签: c++ pointers c++11 vector iterator


【解决方案1】:

如果您从原始向量中删除项目,那么您列出的每一种方法都会有问题。

如果在原始向量中添加项目,第二个和第三个就会有问题。如果您使用push_back 添加项目,第一个不会有问题。

如果不修改原始向量,所有这些都可以。

鉴于此,我建议使用std::vector&lt;size_t&gt;。

【讨论】:

    【解决方案2】:

    我会选择std::vector&lt;size_t&gt; 或std::vector&lt;T*&gt;,因为它们更容易输入。否则,这三个向量几乎是等价的,它们都标识元素的位置。

    如果您知道限制,可以使std::vector&lt;size_t&gt; 使用较小的索引类型。

    如果您预计此向量中会有很多元素,您可能会考虑使用boost::dynamic_bitset 来节省内存并提高 CPU 缓存利用率。每个元素一个位,位位置是原始向量的索引。

    【讨论】:

    • std::vector 如何识别位置?例如,我可以从原始指针中知道向量中项目的索引吗?
    • 是的,肯定可以,因为向量的连续性。超出范围......它适用于其他容器吗?
    • @HumamHelfawi 有些事情告诉我你知道自己问题的答案。这更像是一种附带的数据结构,请参阅youtu.be/sWgDk-o-6ZE 了解更多详细信息。
    • 不,我真的没有:).. 我要去看看谢谢 :)
    【解决方案3】:

    如果你打算删除满足谓词的元素,那么erase-remove idiom是最简单的解决方案。

    如果您打算复制此类元素,那么std::copy_if 是最简单的解决方案。

    如果您打算将容器分成两个分区,即一个容器有好的分区,另一个容器有坏的分区,那么std::partition_copy 是一个不错的选择。

    为了通常允许此类元素的迭代,一个有效的解决方案是返回一系列此类迭代器,这些迭代器将在迭代时检查谓词。我认为标准库中没有这样的迭代器,因此您需要自己实现它们。幸运的是 boost 已经为你做到了:http://www.boost.org/doc/libs/release/libs/iterator/doc/filter_iterator.html

    【讨论】:

      【解决方案4】:

      据我了解,您要解决的问题是两组的交集,我会从标准库中寻找解决方案:std::set_intersection

      【讨论】:

        猜你喜欢
        • 2017-08-29
        • 2011-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-09
        • 2013-12-16
        • 1970-01-01
        相关资源
        最近更新 更多