【问题标题】:C++11 STL merge using move assignment between 2 maps使用 2 个映射之间的移动分配的 C++11 STL 合并
【发布时间】:2014-05-02 11:42:23
【问题描述】:

是否可以将映射从 1 个实例 A 合并到另一个实例,而无需对 B 的复制构造函数进行不必要的调用?

class A
{
    ...
    A & operator=(A && rhs);

    map<string, B> map;
};

class B
{
    B();
    B & B(B && rhs);
    ... 
}

...

A instanceOfA1;
A instanceOfA2;

B instanceOfB1;
B instanceOfB2;
B instanceOfB3;
B instanceOfB4;

instanceOfA1.map.insert( pair<string, B>("one", instanceOfB1));
instanceOfA1.map.insert( pair<string, B>("two", instanceOfB2));
instanceOfA1.map.insert( pair<string, B>("three", instanceOfB3));

instanceOfA2.map.insert( pair<string, B>("four", instanceOfB4));

instanceOfA2 = instanceOfA1;

因此 instanceOfA2 中的映射包含 B 的所有四个实例。

编辑:代码中的固定实例。

【问题讨论】:

  • 不应该是instanceOfA2 = move(instanceOfA1)吗?

标签: c++ c++11 map stl


【解决方案1】:

是否可以将映射从 1 个实例 A 合并到另一个实例,而无需对 B 的复制构造函数进行不必要的调用?

很遗憾,没有。有一个proposal 允许从一个地图中删除元素并插入到另一个地图中,但它未被接受。有一些计划来修改论文并在未来提出新的建议。

最好的办法是插入新元素,但要确保它们使用 B 的移动构造函数而不是复制:

for (auto& p : A1)
  A2.insert(std::move(p));

这也可以通过move_iterators 完成:

A2.insert(std::make_move_iterator(A1.begin()), std::make_move_iterator(A1.end()));

注意std::map中的key_typeconst,所以键类型不能移动,只会移动映射类型(B对象)。这意味着A1 仍将包含与最初相同数量的元素,但B 对象将被移出,因此您可能希望在之后执行此操作:

A1.clear();

【讨论】:

  • 是的,我只是想在我的回答中写下。
  • @user657267,是的,但是地图中的键是const,所以不能移动。映射类型可以移动。
  • 这就是 OP 想要的,不是吗?
  • @jrok,我假设 OP 也想要 A2 中的相同键 :) 我的意思是键将被复制,只有映射的值可以移动。如果键是例如unique_ptr你被卡住了,它不起作用。
猜你喜欢
  • 2011-04-08
  • 2016-04-06
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-04
相关资源
最近更新 更多