The minimal example of the problem I'm having is reproduced below:
#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;
}
With the error error: assignment of data-member ‘foo::value’ in read-only structure
. I feel like I'm missing something simple here, but why am I unable to modify the member x
i开发者_Python百科n my class?
Objects in a set
are immutable; if you want to modify an object, you need to:
- make a copy of the object from the
set
, - modify the copy,
- remove the original object from the
set
, and - insert the copy into the
set
It will look something like this:
std::set<int> s;
s.insert(1);
int x = *s.begin(); // (1)
x+= 1; // (2)
s.erase(s.begin()); // (3)
s.insert(x); // (4)
Given that the "x" variable is not involved in the less-than comparison, it would be safe in this case to make "x" mutable, allowing you to modify it from within the set. Your class definition would then become:
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;
}
};
And you can now use it in the std::set and modify x as you like. In this case it is pointless to keep two copies of the data structure as the previous poster has suggested.
From the definition of the operator<
(i.e. considering only the value return value < rhs.value
and ignoring the x
), I am wondering whether you want a map
instead of a set
. In map
, the second
value is mutable.
精彩评论