定义矢量的unordered_map的最佳方法

时间:2014-01-12 08:23:34

标签: c++ c++11 vector

在定义std::unordered_map这样的

时,在性能方面是否相同
unordered_map<int, std::vector<ClassA>>

并且喜欢这个?

unordered_map<int, std::unique_ptr<std::vector<ClassA>>>

对于std::vector<ClassA>部分,无论如何我都在使用std::move

2 个答案:

答案 0 :(得分:4)

鉴于unordered_map从不移动/复制其节点,它们在复杂性方面应该同样快。但请记住

std::unordered_map<int, std::vector<ClassA>>
当你想要访问向量的数据时,

有一个更少的间接:

std::unordered_map -> [node -> std::vector] -> data

其中内部节点可能包含向量。 OTOH:

std::unordered_map<int, std::unique_ptr<std::vector<ClassA>>>

结果

std::unordered_map -> [node -> std::unique_ptr] -> std::vector -> data

现在,该节点仅包含需要实际解除引用才能到达std::unique_ptr的{​​{1}}。

答案 1 :(得分:1)

我认为你的问题可以用不同的方式说明,并分为两部分:

  • Internaly,当std::unordered_map<>复制而不移动时?
  • std::unordered_map<>插入/检索元素是否始终有办法避免复制?

对于问题的第一部分,答案是否定的。在重新散列期间甚至没有调用移动(参见this question)。您可以确定,如果您插入/检索元素而不复制,则不会有副本。

现在,问题的第二部分。

每次insertemplace或使用operator[]进行分配时,rvalue引用都会出现重载,但您必须确保代码允许使用此类代码一个东西。避免:my_map[index] = my_vector;甚至my_map.insert(std::make_pair(index, my_vector));,因为这不会调用rvalue ref oveload。使用std::move或直接传递右值,或使用初始化列表。

现在,在使用迭代器或使用for循环检索数据时,只要在元素上使用引用就应该没有问题,例如:

for (auto& my_element: my_map) { ... }

而不是:

for (auto my_element: my_map) { ... }