在std :: map中访问元素的最有效方法是什么?

时间:2019-02-06 14:37:24

标签: c++ iterator stdmap

我有一个std::map<some_type, std::vector<another_type>>作为类中的静态变量。我希望所述类的对象对应于地图矢量中的元素。我的直接想法是只使用为向量和映射存储一个迭代器,但是我还考虑了存储键的副本,以便可以使用map::find查找与它关联的值。推荐哪种方法或更有效?

代码

class example_class
{
private:
    static std::map<some_type, std::vector<another_type>> my_list;

    some_type::iterator map_it;

    // I could either use this
    std::vector<another_type>::iterator location_in_vector_it;

    // or this
    some_type copy_of_key;

public:
    // the constructor creates a new element, or adds the value to the end
    // of the vector in the preexisting element.
    example_class(key, val);
};

2 个答案:

答案 0 :(得分:0)

如果my_list的大小发生变化(除非您之前保留了所有内容),则无法将迭代器存储到my_list中的向量。

最简单的方法是将键然后将索引存储在向量中,假设您只是回退新元素而从不删除旧元素。最好的方法是在地图中使用索引进行迭代。

答案 1 :(得分:0)

推荐的方法是编写正确,易于理解且有意义的代码。至于效率:

  • 如果vector可以增长,则存储vector的迭代器是个坏主意,因为vector::insert可以无效迭代器。
  • 将索引存储到vector中(如果可以的话-这些向量如何变化?)允许在 O(1)时间获得元素,但您仍然需要找到向量。

  • 存储map的迭代器将使您能够在 O(1)时间内找到向量,并且该迭代器在map为修改(除非您删除迭代器指向的条目)。

    • vector中存储对map的引用类似于使用迭代器,并且可能导致代码更具可读性。
  • 存储密钥并使用map::find将使您能够在 O(lg n)时间内找到向量。这种方法可以处理您正在寻找的向量已从map中删除的情况。

因此,最安全的方法是存储键和索引,并编写代码来处理找不到元素的情况。但是.... 这是应该能够发生的事情吗?是否要允许其他人(可能是同一类型的另一个对象)删除对象的元素?可能不是,因为每个对象都应该“对应于一个元素”。您的设计有问题吗?

如果我这样做,则可能要确保不会粗鲁地拿走对象的元素。一种方法是使用shared pointers。我可能会考虑存储std::vector<another_type>,而不是将map存储在std::vector<std::shared_ptr<another_type>>中。根据对象破坏时应该发生的情况,我可以将shared_ptr更改为weak_ptr,以便静态容器不维护不再存在的对象的数据。无论哪种情况,每个对象都可以为其元素维护自己的shared_ptr。这样可以快速访问元素,并确保元素不会在对象被破坏之前被破坏。

当然,最理想的方法取决于您将这些元素存储在静态容器中的原因。