我必须为这个问题找到一个有效的解决方案。我有两张地图。我必须将一些元素从map1移动到map2(即从map1擦除并放入map2)。 我有钥匙通过它找到map1中的元素,即我现在正在做的事情:
bool temp;
temp = map1[key1];
map2[key1]=temp;
map1.erase(key1)
我为每个键(循环中)执行此操作
我的问题是我的解决方案是否更便宜 (我使用C ++ 11编译器)
答案 0 :(得分:1)
std :: map文档:http://www.cplusplus.com/reference/map/map/
for (auto key : keys) // keys of elements to move
{
try {
map2[key] = std::move(map1.at(key)); // here is the C++ 11 optimization you looked for
map1.erase(key);
}
// handle error if map1 does not store any element with current key
catch (std::out_of_range & ex) {
// TODO handle error
}
}
答案 1 :(得分:1)
理想的解决方案只有在C ++ 17中才有可能: map::extract()
Std :: map通常实现为二叉树, 一棵二叉树为每个内存对象存储一个键值条目。 在这种假设下,可以通过简单地交换该内存的所有权来移动条目。 只需翻转相关的指针(包括重新平衡两棵树)即可完成此操作,如果最终结果要同时更改两棵树,则必须进行更新。
这不仅避免了在内存中移动对象,而且避免了任何内存分配和释放(具有不可预测的最坏情况性能)。
在C ++ 17之前,您必须实现自己的映射才能被允许这样做。
示例:
// Before Darwin, it was thought that whales were fish.
std::map<int, std::string> fish{{1,"whaleshark"}, {2,"whale"}, {3,"shark"}};
std::map<int, std::string> mammalia{{1,"cat"}, {2,"dog"}};
// Oops, the whale belongs to mammalia.
auto whale = fish.extract(2);
whale.key() = 3;
mammalia.insert(std::move(whale));
答案 2 :(得分:0)
你的临时变量是没有意义的;只写:
map2[key1] = map1[key1];
map1.erase(key1);
...虽然您的编译器已经可能为您做出“优化”。
关于价值本身,bool
已经变得像原子一样 - 没有任何神奇的技巧可以让你更快地复制它。
你可以(只要肯定已经存在map1[key1]
)就是要消除其中一个地图查找和零初始化:
auto it = map1.find(key1);
assert(it != map1.end());
map2.insert(std::make_pair(key1, it->second));
map1.erase(it);
但看看这是多么富有表现力!除非你确实遇到性能问题,否则不要这样做。
答案 3 :(得分:0)
如果value_type
有默认构造函数,那么在名为std::swap
的STL中,您不需要C ++ 11移动语义,这是一件好事。
std::swap(map1[key], map2[key]);
map1.erase(key1);
在您的情况下,我认为它只是复制bool
值。但是,如果你的程序速度变慢,那么复制key_type
我恐怕似乎无法使用这两个地图而不在它们之间移动条目,因为key_type
总是const
合格所以不能移动。
答案 4 :(得分:0)
通过迭代器插入整个地图,然后清除原始地图。
map2.insert(map1.begin(), map1.end());
map1.clear();