2009-06-20 44 views
4

如果集合中元素的值發生更改,則排序可能不再正確。正如這個小程序所示:如何告訴std ::設置爲'刷新'其排序?

#include <algorithm> 
#include <iostream> 
#include <set> 
#include <string> 

struct Comp 
{ 
    bool operator()(const std::string * lhs, const std::string * rhs) 
    { 
     return *lhs < *rhs; 
    } 
}; 

int main() 
{ 
    typedef std::set<std::string*, Comp> MySet; 
    MySet mySet; 

    std::string * a = new std::string("a"); 
    mySet.insert(a); 

    std::string * c = new std::string("c"); 
    mySet.insert(c); 

    std::string * b = new std::string("b"); 
    mySet.insert(b); 

    for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it) 
    { 
     std::cout << *(*it) << std::endl; 
    } 

    // Ouput has correct order: 
    // a 
    // b 
    // c 


    *b = "z"; 
    std::cout << std::endl; 

    std::string * d = new std::string("d"); 
    mySet.insert(d);  

    for (MySet::iterator it = mySet.begin(); it != mySet.end(); ++it) 
    { 
     std::cout << *(*it) << std::endl; 
    } 

    // Output no longer ordered correctly: 
    // a 
    // d 
    // z 
    // c 

    return 0; 
} 

如何告訴設置'刷新'其內部排序?

+0

值不應該改變。 'value_type`應該是`std :: set `(儘管我相信VS不遵守這個規則?) – 2012-02-01 14:34:28

+0

值類型是用戶通過的,並且添加了一個頂級const。如果用戶傳遞`std :: string *`,值類型將是`std :: string * const`。沒有規定禁止用戶傳遞不強制值的排序位置的不變性的事物;有一條規則說,以這種方式修改值會產生未定義的行爲。 – 2013-10-18 16:12:20

回答

9

非常類似的主題在這裏(雖然不是很重複,因爲你存儲指向可變對象使用自定義比較):

what happens when you modify an element of an std::set?

基本上不做你想要什麼去做。相反,如果要修改set保存指針的對象,請首先刪除指針,然後修改該對象,然後重新插入指針。

5

簡而言之,你做不到。如果您將一個物品放入一個集合中,則不應以改變其順序的方式更改該物品。如果您需要以這種方式更改項目,則需要將其從set(set :: erase)中刪除,並用新值重新插入新項目(std :: insert)。

1

值得指出的是,如果您使用vs 2008,std::set實現支持非常量迭代器,使您使用該庫成功描述的代碼可以編譯成功。在其他stl實現中(例如sgi's),set::const_iteratorset::iterator屬於同一類型,它會抱怨明確設置新的鍵值。

+1

設置迭代器在標準中是const。如果您嘗試通過迭代器更新集合的成員,則應該得到編譯錯誤。 – jkp 2009-06-23 08:21:04

0

使用不同的比較謂詞將其複製到自身中。

std::set MySet(); 

/* add entries*/ 

MySet = std::set(MySet.begin(), MySet.end(), Comp); 

通常這被用來指定一個不同的比較操作中,例如,使用一個存儲的類/結構的不同部分,以排序。

2

如果一個元素的一組值更改

停止!這不能合法發生。

std::set沒有提供任何方法來做你所要求的,因爲它已經是不需要手動重新訂購的先決條件。

相關問題