C++ - 修改所有地图元素的键

use*_*418 2 c++ stdmap

我们考虑一下这段代码:

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.这不起作用,因为循环继续.有没有一种快速的方法使它工作?

Ker*_* SB 5

在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)

这需要节点的内存分配,因此新的基于拼接的解决方案更有效.

在任何一种情况下,我们都可以使用提示插入,因为我们以相同的顺序重建元素,因此最新的元素总是插在最后.