通过迭代器更改类成员

时间:2010-08-12 13:14:12

标签: c++ stl iterator const

我正在学习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);
}

我认为这应该是可行的,就像你在foreach循环中用Java做的那样。编译时我得到error: passing ‘const A’ as ‘this’ argument of ‘void A::setVal(int)’ discards qualifiers

查看STL集的来源,我看到begin()仅作为const方法可用,我认为这可能是问题所在。在setVal()方法上使用const进行混乱总是会出现相同的错误,因为我想修改A的值,所以没有多大意义。

这是用循环改变一堆A值的错误方法吗?

2 个答案:

答案 0 :(得分:5)

STL集不允许您更改它存储的值。它通过迭代器(而不是集合中的实际对象)返回对象的副本来实现。

set这样做的原因是因为它正在使用&lt;为了对集合进行排序,它不希望每次取消引用迭代器时都重新映射整个树,因为它不知道你是否改变了改变排序的任何东西。

如果您需要更新集&lt;&gt;,请删除旧值并添加新值。

编辑:刚刚检查了SGI STL的来源,它说:

 typedef typename _Rep_type::const_iterator iterator;

因此,set :: iterator只是一个set :: const_iterator

答案 1 :(得分:1)

来自this page,似乎begin()以及非const方法存在。

也许您的集合作为const引用传递给方法?

修改

引用的页面错误。正如Scharron所说,对于有序容器,没有非const begin()(或end())方法。

我会告知网站他们的错误(这不是他们做的第一次;)