#c #class #object #set
#c #класс #объект #набор
Вопрос:
Я использую набор для хранения объектов. Я хочу внести изменения в первый объект в наборе. Это то, что я пробовал:
set<myClass>::iterator i = classlist.begin();
i->value = 0;
Это ошибка, которую я получаю:
error: read-only variable is not assignable
Как переменная стала доступной только для чтения? Как это можно изменить?
Комментарии:
1. Пожалуйста, расскажите нам, что
classlist
такое.2. classlist — это набор, содержащий объекты MyClass.
3. ошибка, извините, что такое
myClass
? Более конкретно, как он определяет operator< ?4. Я перегружаю оператор < для набора вне MyClass, чтобы MyClass можно было добавить в набор.
Ответ №1:
Объекты в наборе фактически доступны только для чтения — вы не можете изменить значение элемента набора на месте. Все, что вы можете сделать, это удалить его и добавить новый элемент с требуемым новым значением. Это ограничение необходимо из-за реализации std::set в двоичном дереве.
Комментарии:
1. Существуют ли какие-либо другие контейнеры, похожие на set, которые не доступны только для чтения?
2. Да, аналогичным образом вы не можете изменить ключи map.
Ответ №2:
Если вам действительно нужно изменить элемент в set
, элемент должен быть один раз удален из set
и повторно вставлен в это set
.
Например:
set<myClass>::iterator i = classlist.begin();
myClass c = *i;
c.value = 0;
classlist.erase( i );
classlist.insert( c );
Если operator<
for myClass
не ссылается на value
элемент,
вы можете использовать std::map
вместо set
.
Предполагая, что новый, myClass
у которого нет value
элемента,
и предполагая, что тип value
элемента T
равен,
тогда std::map< newMyClass, T >
будет соответствовать цели.
Комментарии:
1. Вы не можете изменить ключи в map.
2. @unapersson: Спасибо за комментарий. Однако, извините, я не вижу особого отношения комментария к ответу. В приведенном выше ответе не говорится об изменении ключа в
map
.
Ответ №3:
Это компилируется под VS2008:
#include <set>
struct myClass{
int value;
int comp;
};
bool operator<(const myClassamp; lhs,const myClassamp; 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;
}
Но это работает только по совпадению. operator<
сравнивает comp
элементы, и мы меняем value
элемент.
Комментарии:
1. Это не компилируется в GCC.
Ответ №4:
в Visual Studio 2010, когда Microsoft обновила STL, они сделали все итераторы постоянными. Итак, set::iterator и set::const_iterator — это одно и то же.
Причина в том, что в наборе ключом являются сами данные, и когда вы меняете свои данные и, следовательно, ключ, который является no no.
Команда Microsoft C сообщила об этом решающем изменении здесь: http://blogs.msdn.com/b/vcblog/archive/2009/05/25/stl-breaking-changes-in-visual-studio-2010-beta-1.aspx
Если вы хотите изменять свои данные и не хотите удалять и вставлять, то вместо этого используйте map.