2013-04-12 15 views
1

在下面的程序中,我有一個帶有非靜態函數void add()的類A。我想使用迭代器爲集合中的每個元素調用add(),但最後一個元素有錯誤。使用迭代器調用STL中的非靜態函數設置

我該如何解決?包含在set<>容器

#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; 
} 
+0

在一個'std :: set'中,你不允許**改變內容(這會弄亂順序)。 '* pos'給你一個'const A',因此你不能在它上面調用非''contst'函數'add()'。如果您想要更改存儲的「A」,則需要使用不同的容器。 – BoBTFish

+0

您不能修改set <>,因此所有集合迭代器都是常量。 http://stackoverflow.com/questions/5632079/why-does-stdset-insert-return-a-non-const-iterator-and-yet-i-cannot-modify – alexrider

+1

'col1.insert(* new A(5 ));'導致內存泄漏,你要查找的語法是'col1.insert(A(5));',即「調用」類名來創建它的一個實例。 –

回答

4

項目被視爲const,並且不能修改。如果他們這樣做了,他們的身份可能會改變,但set<>不會意識到這一點,對其內部結構造成嚴重破壞,因爲物品會存儲在不屬於它的存儲桶中!

例如,請考慮set<>使用您自定義的operator<過載來對其內容進行排序。如果在對象包含在集合中時更改a成員變量,您會發生什麼?該設置不會知道a已更改,並會將對象留在原來的位置。

要解決這個潛在的問題,set<>只給你參考const包含對象的實例。

您只能在此上下文中使用您班級的const成員,並且add()未聲明const。如果要修改對象並使這些更改反映在集合中,則必須複製對象,從集合中刪除原始對象,對您的副本進行更改,然後將副本添加到集合中。

+0

非常感謝,您的解決方案可以幫助我很多! – iLeoDo