Изменение члена класса через итератор - PullRequest
4 голосов
/ 12 августа 2010

Я изучаю C ++ и не могу разобраться с этой проблемой:

У меня есть простой класс A

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;;
    }
}

Тогда у меня есть обычный set<A> myset, который получаетзаполнены insert(A(2, 2.2)); в цикле.

Итерации для получения всех значений не проблема, но я хочу изменить значение в этой итерации:

for(set<A>::iterator iter = set3.begin(); iter != set3.end(); iter++) {
    iter->setVal(1);
}

Я предполагаю, что этобыть выполнимым, как если бы вы делали это на Java в цикле foreach.При компиляции я получаю error: passing ‘const A’ as ‘this’ argument of ‘void A::setVal(int)’ discards qualifiers.

Глядя на источники набора STL, я вижу, что begin() доступен только как метод const, и я думаю, что это может быть проблемой.Возникновение с константой метода setVal() всегда приводило к одной и той же ошибке и не имело бы особого смысла, поскольку я хочу изменить значение A.

.A значения с циклом?

Ответы [ 2 ]

5 голосов
/ 12 августа 2010

Набор STL не позволяет вам изменять значения, которые он хранит.Он делает это, возвращая копию объекта через итератор (не фактическую в наборе).

Причина, по которой набор делает это, заключается в том, что он использует <для упорядочивания набора и не хочетпеределывать все дерево каждый раз, когда вы разыменовываете итератор, что он должен будет сделать, так как он не знает, изменили ли вы что-нибудь, что меняет порядок. </p>

Если вам нужно обновить набор <>,удалите старое значение и добавьте новое.

РЕДАКТИРОВАТЬ: только что проверил источник в SGI STL, и он говорит это:

 typedef typename _Rep_type::const_iterator iterator;

Итак, набор :: итератор это просто набор :: const_iterator

1 голос
/ 12 августа 2010

С этой страницы , кажется, что begin() существует так же, как и неконстантный метод.

Возможно, ваш набор передается в метод как константная ссылка?

РЕДАКТИРОВАТЬ

Ссылочная страница неверна.Как утверждает Шаррон, не существует неконстантного begin() (или end() в этом отношении) метода для заказанных контейнеров.

Я сообщу веб-сайту об их ошибке (это не первый случай, когда они сделали;))

...