Обновление значения ключа в 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 изменения. Просто дважды проверьте, что оператор сравнения все еще возвращает то же самое после его изменения.