2013-04-08 93 views
1

我在下面的代碼中創建了一個std::set,其中元素基於數組進行排序。std :: set元素消失

int weight[] = {0, 1, 58, 21, 10, 21, 24}; 

struct Comp 
{ 
    public: 
    bool operator() (const int &a, const int &b) const 
    { 
     if (weight[a] == weight[b]) 
      return a < b; 
     else 
      return weight[a] < weight[b]; 
    } 
}; 
set<int, Comp> s; 

令人驚訝地,當我改變任何元件的weight陣列中,在所述一組相應的元件消失了。這裏是我的測試功能:

void print() 
{ 
    printf("Elements = "); 
    for(int i = 1; i <= 6; i++) 
     if(s.find(i) != s.end()) 
      printf("%2d ", i);; 
    printf("\n"); 
} 

int main() 
{ 
    for(int i = 1; i <= 6; i++) 
     s.insert(i); 

    print(); 
    weight[2] = 1; 
    weight[5] = 15; 
    print(); 

    return 0; 
} 

輸出:

Elements = 1 2 3 4 5 6 
Elements = 1 3 4 6 

我使用buntu gcc 4.6.3

+0

時間來重新生成一組新的,這是爲什麼奇怪? 's.find()'使用你的'weight'數組,所以如果你改變它,你應該期待'find'的行爲不同。 – 2013-04-08 13:23:40

+2

您正在修改組合後的訂購標準。這是行不通的。 – juanchopanza 2013-04-08 13:24:07

回答

6

每對關聯容器的要求的第C++ 11標準的23.2.4/3:

短語「鍵的等價」是指通過比較施加的等價關係,而不是 operator==在鍵上。也就是說,如果用於比較 對象comp,comp(k1, k2) == false && comp(k2, k1) == false,則兩個鍵​​和k2被認爲是等同的。 對於任何兩個鍵​​和k2在 相同的容器中,調用comp(k1, k2)應始終返回相同的值

既然你沒有履行這個先決條件通過改變權重(和你比較使用這些權重上的一組元素定義排序),你的程序有未定義行爲

1

至於什麼安迪伺機引述一個推論,你就需要在每次你改變你的體重陣列