I am using a set to hold objects. I want to make changes to the first object in the set. This is what I tried:
set<myClass>::iterator i = classlist.begin();
i->value = 0;
This is the error I get:
error: read-only variable is not assignable
How did the variable become read-only? How can it be changed?
The things in a set are effectively read-only - you cannot change the value of a member of a set in situ. All you can do is remove it, and add a new member with the required new value. This restriction is necessary because of the binary tree implementation of std::set.
If you really have to modify the element in set
, the element has to be
once erased from the set
and re-inserted in that set
.
For example:
set<myClass>::iterator i = classlist.begin();
myClass c = *i;
c.value = 0;
classlist.erase( i );
classlist.insert( c );
If operator<
for myClass
doesn't refer the value
member,
you can use std::map
instead of set
.
Assuming a new myClass
which doesn't have value
member,
and assuming that the type of value
member is T
,
then std::map< newMyClass, T >
will meet the purpose.
This compiles under VS2008:
#include <set>
struct myClass{
int value;
int comp;
};
bool operator<(const myClass& lhs,const myClass& rhs){
return lhs.comp<rhs.comp;
}
int main(){
std::set<myClass> classlist;
myClass c;
classlist.insert(c);
std::set<myClass>::iterator i=classlist.begin();
i->value=0;
return 0;
}
But this only works by coincidence. operator<
compares the comp
members and we change the value
member.
in Visual Studio 2010 when Microsoft updated the STL, they made all iterators constant. So set::iterator and set::const_iterator are the same.
The reason is because in a set, the key is the data itself, and when you change your data, and thus the key, which is a no no.
The microsoft C++ team reported on this breaking change here:
http://blogs.msdn.com/b/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
If you want to be modifying your data, and don't want to be removing and inserting, then use a map instead.