如果您知道新键对于地图位置是有效的(更改它不会改变排序),并且您不想删除和添加项目到地图中,您可以使用const_cast
来更改键,就像下面的unsafeUpdateMapKeyInPlace
一样:
template <typename K, typename V, typename It>
bool isMapPositionValidForKey (const std::map<K, V>& m, It it, K key)
{
if (it != m.begin() && std::prev (it)->first >= key)
return false;
++it;
return it == m.end() || it->first > key;
}
template <typename K, typename V>
void unsafeUpdateMapKeyInPlace (const std::map<K, V>& m, typename std::map<K, V>::iterator& it, K newKey)
{
assert (isMapPositionValidForKey (m, it, newKey));
const_cast<K&> (it->first) = newKey;
}
如果您想要一个只在合适的情况下进行原地更改,否则更改映射结构的解决方案:
template <typename K, typename V>
void updateMapKey (const std::map<K, V>& m, typename std::map<K, V>::iterator& it, K newKey)
{
if (isMapPositionValidForKey (m, it, newKey))
{
unsafeUpdateMapKeyInPlace (m, it, newKey);
return;
}
auto next = std::next (it);
auto node = m.extract (it);
node.key() = newKey;
m.insert (next, std::move (node));
}
end()
,不需要进行任何遍历。 - Tony Delroyfind
,有一个遍历(traversal)的过程,然后erase(i)
以迭代器作为参数(而不是要删除的值),避免了另一个遍历,但最终的insert
需要进行第二次遍历来找到新位置插入(因为当键改变时,它可能在一个无关的位置 - 如果你知道新插入应该非常靠近树中的旧插入,可以提供插入提示)。 - Tony Delroy