是否可以通过使用移动语义将临时std :: map temp
的内容插入到另一个std :: map m
中,这样就不会复制临时值,而是重用?
让我们说一个人:
std::map<int, Data> temp;
std::map<int, Data> m;
将值从temp
复制到m
的一种方法是:
m.insert(temp.begin(),temp.end());
我如何将<{1}}元素移动到temp
而不是复制?
答案 0 :(得分:20)
提示: 首先阅读更新!
当前的C ++ 11标准和C ++ 14草案不提供启用此功能的成员函数。正如lavr建议你仍然可以写
m.insert(make_move_iterator(begin(temp)),
make_move_iterator(end (temp)));
将值从源容器移动到目标容器中。但是,容器节点和键都不会被移动。这需要内存分配(至少用于在目标映射中创建新节点)。源容器中的元素数量将保持不变。复制背后的原因很简单:std::map
的值类型为std::pair<const Key,T>
。从const Key
移动本质上是复制密钥(除非有人超载了Key
构造函数,该构造函数需要const Key &&
,我无法想到这是一个充分的理由。
如果您需要将数据从一个容器移动到另一个容器,可以考虑使用std::list
而不是std::map
。它有一个member function splice
,可以在恒定的时间内将元素从一个列表移动到另一个列表。
<强>更新强>
自C ++ 17以来,函数std::map::merge()
基本上将一个std::map
的所有元素放入另一个std::map
而不移动或复制实际元素,而是通过重新指定内部指针只要。它与自{+ C} 98以来存在的std::list::splice()
非常相似。
所以你可以写
m.merge( temp );
实现目标。这比将所有元素从一个容器复制或移动到另一个容器更有效。
但要注意!冲突的密钥将无法解决:对于重合的密钥,将不会执行任何操作。
答案 1 :(得分:7)
没试过,但我认为std::move_iterator应该有所帮助:
using it = std::map<int, Data>::iterator;
using mv = std::move_iterator <it>;
m.insert(mv(temp.begin()),mv(temp.end()));
答案 2 :(得分:3)
我不认为这是可能的。对于其他容器,我会建议std::move_iterator
适配器,但这不起作用,因为地图的键是const。
换句话说,您无法从地图中逐个移出元素,因为这可能会更改地图不允许的键。
并且无法从一张地图批量移动到另一张地图。列表支持拼接,但我担心树木不会。