我们考虑一下这段代码:
std::map< int, char > charMap;
for( auto& i : charMap )
{
charMap[ i.first + 1 ] = charMap[ i.first ];
charMap.erase( i.first );
}
Run Code Online (Sandbox Code Playgroud)
假设地图有一些带有randomed键的值.我试图将键移动1.这不起作用,因为循环继续.有没有一种快速的方法使它工作?
在C++ 17中,您可以使用节点提取和拼接(参见P0083R3):
std::map<int, char> tmpMap;
for (auto it = charMap.begin(); it != charMap.end(); )
{
auto nh = charMap.extract(it++); // node handle
++nh.key();
tmpMap.insert(tmpMap.end(), std::move(nh));
}
tmpMap.swap(charMap);
Run Code Online (Sandbox Code Playgroud)
循环提取连续的映射节点,对其进行变异,然后将节点重新插入tmpMap(现在使用不同的密钥).最后,它charMap是空的并tmpMap包含所有元素及其修改后的键,因此我们将两者交换.
在C++ 17之前,您必须复制(或移动)值数据以插入带有新键的新元素.
std::map<int, char> tmpMap;
for (auto & p : charMap)
tmpMap.emplace_hint(tmpMap.end(), p.first + 1, std::move(p.second));
tmpMap.swap(charMap);
Run Code Online (Sandbox Code Playgroud)
这需要节点的内存分配,因此新的基于拼接的解决方案更有效.
在任何一种情况下,我们都可以使用提示插入,因为我们以相同的顺序重建元素,因此最新的元素总是插在最后.