在定义std::unordered_map
这样的
unordered_map<int, std::vector<ClassA>>
并且喜欢这个?
unordered_map<int, std::unique_ptr<std::vector<ClassA>>>
对于std::vector<ClassA>
部分,无论如何我都在使用std::move
。
答案 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)
我认为你的问题可以用不同的方式说明,并分为两部分:
std::unordered_map<>
复制而不移动时?std::unordered_map<>
插入/检索元素是否始终有办法避免复制?对于问题的第一部分,答案是否定的。在重新散列期间甚至没有调用移动(参见this question)。您可以确定,如果您插入/检索元素而不复制,则不会有副本。
现在,问题的第二部分。
每次insert
,emplace
或使用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) { ... }