2010-08-12 153 views
4

我学习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的值与循环?

+0

+1,因为它似乎真的你搜索的第一个自己,这始终是一件好事,当你学到新的东西。 – ereOn 2010-08-12 13:17:15

+0

请注意'val1.ival 2010-08-12 13:19:05

+0

@Pedro:谢谢,现在你说出来了,很明显,但是我自己看不到。 – DrColossos 2010-08-12 13:23:55

回答

5

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

集合这样做的原因是因为它使用<来对集合进行排序,并且它不想在每次解引用迭代器时都重新构造整个树,因为它不知道迭代器,因为它不知道如果你改变了改变顺序的东西。

如果您需要更新集合<>,请删除旧值并添加一个新值。

编辑:刚刚检查源SGI STL和它说的:

typedef typename _Rep_type::const_iterator iterator; 

所以,一套:: iterator是只是一组::为const_iterator

+0

这是否意味着我只是运气不好而试图用一套而不用另一个容器?这将与矢量或列表或...一起工作吗? – DrColossos 2010-08-12 13:18:58

+0

是的,这适用于'std :: vector'。 – 2010-08-12 13:19:45

+1

你的意思是一个const&,而不是一个副本。 如果它是一个副本,它不会是const – Scharron 2010-08-12 13:21:40

1

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

也许你的设置作为const引用传递给方法?

编辑

引用的页面是错误的。正如Scharron所述,对于有序集装箱,没有非常规的begin()(或end())方法。

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

+0

不(至少我不这么认为)。我使用'set myset;'而不是像上面描述的那样添加'A'。 – DrColossos 2010-08-12 13:20:21

+0

我自己知道这个网页,伟大的资源!如果源代码中的定义被说成是const,那么非const'begin()'来自哪里? – DrColossos 2010-08-12 13:21:44

+0

这是一个错误。 迭代器和const_iterator在有序容器上是相同的类型(因此只有一个'begin()const'和'end()const'方法) – Scharron 2010-08-12 13:23:11