Какова альтернативная структура данных, подобная множеству, когда необходимо изменить элементы? - PullRequest
0 голосов
/ 23 сентября 2011
Наборы

STL спроектированы таким образом, что невозможно изменить элементы в наборе (по уважительной причине см. stackoverflow ). Предположим, однако, что у меня есть структура, в которой ключом выступает только один из членов. Есть ли альтернативная структура данных для набора. Я действительно хочу точно поведение наборов, кроме этой неспособности изменить поле или элемент, который не является ключевым.

Ответы [ 4 ]

2 голосов
/ 23 сентября 2011

На ум приходит несколько вариантов:

  1. Настройте ваши структуры данных так, чтобы вместо них использовалось std :: map
  2. Используйте std :: set, но удалите элемент, который вы хотитеизмените и замените его на обновленное значение.
  3. Разработайте и внедрите структуру данных, которая удовлетворяет вашим требованиям.

Я бы посчитал первые два варианта предпочтительными;последний следует использовать только в том случае, если вы не можете адаптировать свою проблему или существующие контейнеры STL для удовлетворения своих потребностей.

1 голос
/ 23 сентября 2011

Может быть, пришло время изменить дизайн, рассматривая std :: map вместо std :: set.

вместо

struct A
{
   K key;
   V val;
};

set<A> a;

рассмотреть

std::map<K,V> m;

вы можете сделать

m[k] = v;
1 голос
/ 23 сентября 2011

Объявите неключевой ключ как mutable, тогда вы сможете изменить его.

struct A
{
   KeyType key;
   mutable NonKeyType nonkey;
   //..
};

std::set<A> aset;
//...

const A & a = *aset.begin();
a.nonkey = newValue; //you can modify it even if the object `a` is const.

Вы должны убедиться, что nonkey действительно неключевой;он не должен принимать участие в operator< функции сравнения.

0 голосов
/ 23 сентября 2011

Нет способа обеспечить, чтобы члены класса, используемые в предикате упорядочения, не изменялись. Модификация членов, используемых в предикате упорядочения, потенциально может нарушить набор.

Простой способ заставить компилятор позволить вам использовать набор с изменяемыми элементами - пометить элементы как изменяемые:

 class Foo
 {
     std::string myVal1;
     mutable std::string myVal2;
 public:
     bool operator<(const Foo& rhs)const {
         return myVal1 < rhs.myVal;
     }
 };

Затем вы должны вручную убедиться, что Foo::operator<() никогда не использует myVal2 в сравнении. Это возможно, но это Плохая идея (тм) . Вы можете пометить этот конкретный оператор огромным комментарием, но вы не можете автоматически дублировать этот комментарий во все пользовательские функции сравнения (std::set<> принимает это как второй параметр).

Реальный способ достичь того, чего вы хотите - это использовать std::map<>. Поместите часть «ключ» в ключ, а часть «значение» в значение.

...