Обновление значения ключа в std:: map
Предположим, что мы имеем простую структуру, такую как
struct T{
int x;
int y;
};
T t1, t2;
Также предположим, что у меня есть map<T, int> myMap
и что две структуры типа T
сравниваются, используя только их значения x
. То есть t1 < t2
iff t1.x < t2.x
. Я пытаюсь обновить некоторые значения y
для ключей над myMap. Это не должно влиять на то, как карта видит ключи. Есть ли способ, кроме удаления старого элемента и вставки нового?
Ответы
Ответ 1
Если вы уверены, что y
не участвует в "логическом состоянии" вашего класса и является просто деталью реализации, вы можете объявить его mutable
:
struct T
{
int x;
mutable int y;
bool operator<(const T& rhs) const { return x < rhs.x; }
};
Теперь вы должны иметь возможность изменить y
:
for (auto it = m.begin(); it != m.end(); ++it)
{
it->first.y = -2; // ouch? But it won't invalidate the map invariants.
}
Ответ 2
Нет, map
не может позволить вам изменять ключи, потому что это может привести к аннулированию инварианта карты (упорядочение элементов) - вы знаете, что это не так, но map
не может этого знать, поэтому он ошибается на стороны предостережения и запрещает это.
Удалить и повторно вставить правильный способ сделать это. Лечите ключи как неизменные.
Ответ 3
Если y
не участвует в сравнении, вы можете пометить его как mutable
, поэтому его можно изменить, даже если значение постоянное.
Ответ 4
Ключом std::map
являются константы. Поэтому вы не можете его изменить.
Кроме того, если вы используете только x
для сравнения ключей, то почему вы std::map<T,int>
? Почему не это:
std::map<int, std::pair<T,int> > data; //where keys would be t.x
В конце концов, на вашей карте эффективны клавиши t.x
.
Ответ 5
Вы можете изменить T::y
, если это не влияет на поведение оператора сравнения. С другой стороны, это плохой стиль для изменения ключа карты, он должен быть неизменным. Некоторые реализации стандартной библиотеки позволяют изменять ключ.
Ответ 6
Клавиши являются константами на карте, попробуйте скопировать новые значения в новую карту.
Ответ 7
Как и кошка, вы не должны менять ключи по множеству веских причин, но, похоже, вы достаточно хорошо знаете, чтобы двигаться вперед.
Отбросьте константу ключа с помощью const_cast, и вы не можете делать всевозможные повреждения.... err изменения. Просто дважды проверьте, что оператор сравнения все еще возвращает то же самое после его изменения.