1

在下面的程序中,我有一个A带有非静态函数的类void add()。我想使用迭代器来调用add()集合中的每个元素,但是最后一个元素有错误。

我该如何解决?

#include <iostream>
#include <set>

using namespace std;

class A
{
private:
    int a;
public:
    A(int x) { a = x; }
    void add() {a = a + 1; }
    bool operator<(A x) const { return a < x.a; }
};

int main()
{
    //type of the collection
    typedef set<A> IntSet;

    //define a IntSet type collection
    IntSet col1;
    IntSet::iterator pos;

    //insert some elements in arbitrary order
    col1.insert(A(3));
    col1.insert(A(4));
    col1.insert(A(5));

    //iterator over the collection and print all elements

    for(pos = col1.begin(); pos != col1.end(); ++pos)
    {
        (*pos).add();
        // ERROR!: Member function 'add' not viable:
        // 'this' argument has type'const value_type' 
        // (aka 'const A'), but function is not marked const
    }
    cout << endl;
}
4

1 回答 1

4

包含在set<>容器中的项目被考虑const并且不能被修改。如果他们这样做了,他们的身份可能会改变,但set<>不会意识到这一点,对其内部结构造成严重破坏,因为一个项目将被存储在一个不属于它的桶中!

例如,考虑set<>使用您的自定义operator<重载来对其内容进行排序。a如果在对象包含在集合中时更改成员变量,您期望会发生什么?集合不会知道发生了a变化,并将对象留在原来的位置。

要解决此潜在问题,set<>仅提供const对包含对象实例的引用。

您将只能const在此上下文中使用您的类的成员,并且add()未声明const. 如果要修改对象并将这些更改反映在集合中,则必须制作对象的副本,从集合中删除原始对象,对副本进行更改,然后将副本添加到集合中.

于 2013-04-12T16:14:46.327 回答