移动 std::map 与移动 std::map 的所有元素

Move a std::map vs move all the elements of a std::map

提问人:Yves 提问时间:11/11/2021 最后编辑:JeJoYves 更新时间:11/11/2021 访问量:376

问:

std::map<int, Obj> mp;
// insert elements into mp

// case 1
std::map<int, Obj> mp2;
mp2 = std::move(mp);

// case 2
std::map<int, Obj> mp3;
std::move(std::begin(mp), std::end(mp), std::inserter(mp3, std::end(mp3));

我对这两种情况感到困惑。它们完全一样吗?

C++ 11 移动 地图 C++-标准库

评论

1赞 273K 11/11/2021
第一个具有恒定的时间复杂度,第二个具有 n 个对数 n时间复杂度。
0赞 Marek R 11/11/2021
不,它们是不一样的。请注意,第二种情况下的目标地图可能略有不同(例如,顺序不同)。情况 1 速度超快,情况 2 必须为 .mp3
0赞 Aconcagua 11/11/2021
请注意,第一个副本只是将整个树从第一个地图移动到第二个地图,第一个(通常)保持为空,而第二个变体由于第二个树的性质而保持第二棵树中的节点不变,只是它们的内容被移动:假设,然后向量的内容被移动,而第一个地图中的向量本身保持不变(通常为空)。std::movestd::map<std::vector<...>>

答:

5赞 Ted Lyngmo 11/11/2021 #1

不,它们是不一样的。

  • 案例 1 立即移动整体的内容。的内部指针被“移动”到 - 映射中的任何 s 都不会受到影响。mapmapmp2pair
  • 案例 2 在地图中逐个移动个人。请注意, s 因此它们不能移动,而是会被复制。 仍将包含与以前一样多的元素 - 但值处于不确定状态。pairmapconstmp
5赞 JeJo 11/11/2021 #2

它们完全一样吗?

,他们不是!

第一个调用 std::map4 的移动构造函数,移动操作将在类/数据结构级别完成。

[...]

  1. Move 构造函数。 在容器移动构造 () 后,对 other 的引用、指针和迭代器(结束迭代器除外)仍然有效,但引用现在位于 中的元素。现行标准通过container.requirements.general中的一揽子声明做出此保证,并且正在考虑通过LWG 2321提供更直接的保证overload (4)*this

复杂性

4常数。如果给出 和 ,则为线性。alloc != other.get_allocator()


第二个是从<算法>标头,它执行元素(i.e. key值对)移动到另一个映射。std::move

  1. 将范围 [first, last] 中的元素移动到另一个范围,从 d_first 开始,从第一个开始,一直到最后一个 - 1。执行此操作后,moved-from 范围内的元素仍将包含相应类型的有效值,但不一定与移动前的值相同。

复杂性

确切地说,最后 - 第一次移动任务。