обновление значения ключа в std :: map - PullRequest
12 голосов
/ 30 августа 2011

Предположим, у нас есть простая структура, такая как следующая

struct T{
  int x;
  int y;
};
T t1, t2;

Также предположим, что у меня есть map<T, int> myMap и что две структуры типа T сравниваются, используя только их значения x.Т.е. t1 < t2 если t1.x < t2.x.Я пытаюсь обновить некоторые из y значений ключей через myMap.Это не должно влиять на то, как карта видит ключи.Есть ли другой способ, кроме удаления старого элемента и вставки нового?

Ответы [ 7 ]

13 голосов
/ 30 августа 2011

Если вы уверены, что 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's invariants.
}
9 голосов
/ 30 августа 2011

Нет, map не может позволить вам изменить ключи, поскольку это может сделать недействительным инвариант карты (упорядочение элементов) - вы знаете, что это не так, но map не может этого знать, поэтому он ошибаетсясторона предостережения и запрещает это.

Удалите и вставьте заново, это правильный способ сделать это.Относитесь к ключам как к неизменным.

4 голосов
/ 30 августа 2011

Если y не участвует в сравнении, вы можете пометить его как mutable, поэтому его можно изменить, даже если значение является постоянным.

1 голос
/ 30 августа 2011

Вы можете изменить T::y, если это не влияет на поведение оператора сравнения.С другой стороны, модифицировать ключ карты - плохой стиль, он должен быть неизменным.Некоторые реализации стандартной библиотеки позволяют изменять ключ.

1 голос
/ 30 августа 2011

Ключи std::map являются постоянными. Таким образом, вы не можете изменить его.

Кроме того, если вы используете только x для сравнения клавиш, то почему вы std::map<T,int>? Почему бы не это:

std::map<int, std::pair<T,int> > data; //where keys would be t.x

В конце концов, на вашей карте ключи фактически t.x.

0 голосов
/ 30 августа 2011

Как сказал Кэт, вам не следует менять ключи по многим веским причинам, но вы, кажется, знаете достаточно, чтобы двигаться вперед.

Отбросьте константу ключа с помощью const_cast, и вы не сможете выполнять все виды операций.повреждение .... ошибочные изменения.Просто дважды проверьте, что оператор сравнения по-прежнему возвращает то же самое после его изменения.

0 голосов
/ 30 августа 2011

ключи являются постоянными на карте, попробуйте скопировать новые значения в новую карту.

...