Назначение члена-члена в структуре только для чтения, класс в наборе STL - PullRequest
9 голосов
/ 23 сентября 2010

Минимальный пример проблемы, с которой я столкнулся, приведен ниже:

#include <set>
using namespace std;

class foo {
public:
  int value, x;
  foo(const int & in_v) {
   value = in_v;
   x = 0;
  }
  bool operator<(const foo & rhs) const {
   return value < rhs.value; 
 }
};

int main() {
  foo y(3);
  set<foo> F;
  F.insert(y);

  // Now try to modify a member of the set
  F.begin()->x=1;
  return 0;
}

С ошибкой error: assignment of data-member ‘foo::value’ in read-only structure.Я чувствую, что здесь упускаю что-то простое, но почему я не могу изменить члена x в моем классе?

Ответы [ 3 ]

17 голосов
/ 23 сентября 2010

Объекты в set неизменны;если вы хотите изменить объект, вам необходимо:

  1. сделать копию объекта из set,
  2. изменить копию,
  3. удалитьисходный объект из set и
  4. вставьте копию в set

Это будет выглядеть примерно так:

std::set<int> s;
s.insert(1);

int x = *s.begin(); // (1)
x+= 1;              // (2)
s.erase(s.begin()); // (3)
s.insert(x);        // (4)
8 голосов
/ 18 января 2011

Учитывая, что переменная «x» не участвует в сравнении «меньше», в этом случае было бы безопасно сделать изменяемым «x», что позволит вам изменять его из набора. Тогда ваше определение класса станет:

class foo {
public:
  int value;
  mutable int x;

  foo(const int & in_v) : value(in_v), x(0) { }
  bool operator<(const foo & rhs) const {
    return value < rhs.value; 
  }
};

И теперь вы можете использовать его в std :: set и изменять x так, как вам нравится. В этом случае бессмысленно хранить две копии структуры данных, как предлагал предыдущий автор.

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

Из определения operator< (то есть, учитывая только значение return value < rhs.value и игнорируя x), мне интересно, хотите ли вы map вместо setmap значение second является изменяемым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...