通过迭代器更改类成员

发布于 2024-09-13 16:57:53 字数 1132 浏览 2 评论 0原文

我正在学习 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; myset 在循环中被 insert(A(2, 2.2)); 填充。

迭代获取所有值不是问题,但我想在这次迭代中修改值:

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

我认为这应该是可行的,就像您在 Java 中的 foreach 循环中所做的那样。编译时出现错误:将“const A”作为“void A::setVal(int)”的“this”参数传递会丢弃限定符。

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

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

I'm learning C++ and can't get my head around this problem:

I have a simple class 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;;
    }
}

Then I have a regular set<A> myset that gets filled with insert(A(2, 2.2)); in a loop.

Iterating to get all the values is not a problem but I want to modify the value within this iteration:

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

I assume that this should be doable, like you would do it in Java within a foreach loop. When compiling I get error: passing ‘const A’ as ‘this’ argument of ‘void A::setVal(int)’ discards qualifiers.

Looking at the sources of the STL set, i see that begin() is only available as a const method and I think this might be the problem. Messing around with const on the setVal() method got always the same error and wouldn't make much sense since I want to modify the value of A.

Is this the wrong approach of changing a bunch of A's values with a loop?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

小瓶盖 2024-09-20 16:57:54

此页面开始,似乎开始( ) 与非常量方法一样存在。

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

编辑

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

我将向网站通报他们的错误(这不是他们第一次犯下的错误;))

From this page, it seems that begin() exists as well as a non-const method.

Perhaps your set is passed into the method as a const reference ?

EDIT

The referenced page is wrong. As Scharron states, there is no non-const begin() (or end() for that matter) method for ordered containers.

I will inform the website about their mistake (it's not the first they made ;))

秋叶绚丽 2024-09-20 16:57:53

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

set 这样做的原因是因为它使用了 <来对集合进行排序,并且它不想在每次取消引用迭代器时重新创建整个树,而它必须这样做,因为它不知道您是否更改了任何会改变排序的内容。

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

编辑:刚刚检查了 SGI STL 的源代码,它是这样说的:

 typedef typename _Rep_type::const_iterator iterator;

所以,一个 set::iterator 只是一个 set::const_iterator

The STL set does not let you change values it stores. It does that by returning a copy of the object through the iterator (not the actual one in the set).

The reason that set does this is because it's using < to order the set and it doesn't want to remake the entire tree every time you dereference the iterator, which it would have to do, since it doesn't know if you changed anything that changes the ordering.

If you need to update the set<>, remove the old value and add in a new one.

EDIT: just checked source to SGI STL and it says this:

 typedef typename _Rep_type::const_iterator iterator;

So, a set::iterator is just a set::const_iterator

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文