我可以将 std::map 的内容移动分配到另一个 std::map 中吗?
Can I move-assign a std::map's contents into another std::map?
是否可以使用移动语义将临时std::maptemp
的内容插入到另一个std::mapm
中,这样临时的值就不会被复制并重用?
假设一个有:
std::map<int, Data> temp;
std::map<int, Data> m;
将值从temp
复制到m
的一种方法是:
m.insert(temp.begin(),temp.end());
如何将temp
元素移动到m
中,而不是复制?
提示: 请先阅读更新
当前的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
。它有一个成员函数splice
,它在恒定时间内将元素从一个列表移动到另一个列表。
更新:
由于C++17存在函数std::map::merge()
,它基本上将一个std::map
的所有元素放入另一个std::map
,而不移动或复制实际元素,而是仅通过重新初始化内部指针。它与C++98以来存在的CCD_ 18非常相似。
所以你可以写
m.merge( temp );
实现你的目标。这比将所有元素从一个容器复制或移动到另一个容器更有效。
但是要小心!冲突的密钥将不会得到解决:对于重合的密钥,将不会采取任何措施。
还没有尝试过,但我认为std::move_iterator应该在这里有所帮助:
using it = std::map<int, Data>::iterator;
using mv = std::move_iterator <it>;
m.insert(mv(temp.begin()),mv(temp.end()));
我认为这是不可能的。对于其他容器,我建议使用std::move_iterator
适配器,但这不起作用,因为映射的键是const。
换句话说,您不能从地图中一个接一个地移出元素,因为这可能会更改关键点,而地图是不允许的。
而且没有办法只是从一张地图批量移动到另一张地图。列表支持拼接,但恐怕树不支持。
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 使用一个考虑到std::map中键值的滚动或换行的键
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将重物插入std::map
- 使用通用值初始化 std::map,不重复
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- C++:当所有条目都保证是唯一时,替代 std::map
- 使用模板化的键类型定义 std::map,该键类型基于作为参数接收的函数
- 如果 KEY 是 std::list 或 std::vector 而不是值,那么 std::map 的默认行为是什么?
- C++如何创建 std::map
- 从其他容器中移动构造"std::map"
- 将 std::map::emplace 与返回 shared_ptr 的函数一起使用是否正确?
- C++中 std::map 的运行时复杂度是多少?
- 为什么在 std::map 上移动无法将元素从一个映射移动到另一个映射
- 使用重载 [] 运算符返回 std::map() 的可赋值
- std::map, std::unordered_map - 缩小初始值设定项列表中的转换范围
- C++ 使用枚举类对象分配 std::map 值
- 静态 std::map instatiation 在类的方法中调用构造函数吗?
- std::map:当元素不可默认构造时创建/替换元素
- Arduino编译器和STL:使用std::vector和std::map