Changing a classes member through an iterator
I'm learning C++ and can't get my head around this problem:
I have a simple class A
开发者_JAVA技巧class A {
private:
int ival;
float fval;
public:
A(int i = 0, float f = 0.0) : ival(i), fval(f) { }
~A(){ }
void show() const {
cout << ival << " : " << fval << "\n";
}
void setVal(int i) {
ival = i;
}
//const getters for both ival and fval
//used for the default "lesser"
friend bool operator<(const A& val1, const A& val2) {
return val1.ival < val2.ival ? true : false;;
}
}
Then I have a regular set<A> myset
that gets filled with insert(A(2, 2.2));
in a loop.
Iterating to get all the values is not a problem but I want to modify the value within this iteration:
for(set<A>::iterator iter = set3.begin(); iter != set3.end(); iter++) {
iter->setVal(1);
}
I assume that this should be doable, like you would do it in Java within a foreach loop. When compiling I get error: passing ‘const A’ as ‘this’ argument of ‘void A::setVal(int)’ discards qualifiers
.
Looking at the sources of the STL set, i see that begin()
is only available as a const method and I think this might be the problem. Messing around with const on the setVal()
method got always the same error and wouldn't make much sense since I want to modify the value of A
.
Is this the wrong approach of changing a bunch of A
's values with a loop?
The STL set does not let you change values it stores. It does that by returning a copy of the object through the iterator (not the actual one in the set).
The reason that set does this is because it's using < to order the set and it doesn't want to remake the entire tree every time you dereference the iterator, which it would have to do, since it doesn't know if you changed anything that changes the ordering.
If you need to update the set<>, remove the old value and add in a new one.
EDIT: just checked source to SGI STL and it says this:
typedef typename _Rep_type::const_iterator iterator;
So, a set::iterator is just a set::const_iterator
From this page, it seems that begin()
exists as well as a non-const method.
Perhaps your set is passed into the method as a const reference ?
EDIT
The referenced page is wrong. As Scharron states, there is no non-const begin()
(or end()
for that matter) method for ordered containers.
I will inform the website about their mistake (it's not the first they made ;))
精彩评论