Если вы знаете, что новый ключ действителен для положения на карте (его изменение не изменит порядок), и вам не нужны дополнительные операции по удалению и добавлению элемента на карту, вы можете использовать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;
}
// Only for use when the key update doesn't change the map ordering
// (it is still greater than the previous key and lower than the next 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));
}