2014-09-18 35 views
-1

我預計std::set的順序與std::liststd::vector一致,只是值不會被第二次附加。 MSVC 110證明我錯了。我希望下面的代碼如下所示的結果產量,上運行ideone(http://ideone.com/e47GwQ)代碼時(不知道他們使用的編譯器和版本,雖然)這是這樣的。在std :: set中的順序和std :: unordered_set的區別

#include <iostream> 
#include <set> 

template <typename C> 
int insert_get_index(C& container, typename C::value_type value) 
{ 
    typename C::iterator it = container.insert(value).first; 
    return std::distance(container.begin(), it); 
} 

int main() 
{ 
    int a = 3, b = 1, c = 9; 
    std::set<int*> set; 

    std::cout << insert_get_index(set, &a) << "\n"; 
    std::cout << insert_get_index(set, &b) << "\n"; 
    std::cout << insert_get_index(set, &c) << "\n"; 
    std::cout << insert_get_index(set, &a) << "\n"; 
    std::cout << insert_get_index(set, &b) << "\n"; 
    std::cout << insert_get_index(set, &c) << "\n"; 

    return 0; 
} 
0 
1 
2 
0 
1 
2 

運行在Visual Studio 2012的代碼產生你可以看到下面的東西。

0 
0 
2 
1 
0 
2 

現在,爲什麼我減薄std::set的行爲如上所述?因爲cplusplus.com聲明

集合是容器,它按照特定順序存儲唯一元素。

另外還有std::unordered_set

  1. 我沒有理解錯誤的文件和std::set反而值排序
  2. ,什麼是std::unordered_set的呢?
  3. 是否有不同的標準庫的容器,滿足我的要求嗎?
+0

「是否有不同的標準庫容器滿足我的要求?」 - 你有什麼要求? – 2014-09-18 16:52:46

+0

@MikeSeymour如上所述,我期望'std :: set'保持插入值的順序,但只插入一次。這是我的要求。 – 2014-09-18 16:53:17

+0

'std :: set'是一個通常用紅黑樹實現的有序關聯容器。 – 2014-09-18 16:53:35

回答

2

難道我理解不正確的文件和std ::設置是不是值進行排序?

它確實是值排序。除非您提供自己的比較器,否則將通過使用std::less進行比較來對它們進行排序。對於大多數類型,這使用<。對於指針(通常不能以明確定義的方式與<進行比較),它定義了未指定但一致的排序。 (在具有線性地址空間的通用平臺上,這可能只是比較地址值;但不能依賴此地址)。

因此,在這種情況下,存儲指向局部變量,這取決於其中編譯器選擇爲每個變量,這可能會發生變化,從編譯器的編譯器分配存儲空間。

那又是什麼std::unordered_set呢?

當您不關心訂單時,這可以提供更好的性能。它使用散列表進行恆定時間查找,而set使用搜索樹(或類似的東西)來進行對數時間查找。

是否有不同的標準庫的容器,滿足我的要求嗎?

不,不存在既保持插入順序又提供快速的基於值的查找的容器。根據您的具體要求,您可以使用vector來維護訂單,並使用std::find進行線性時間查詢;也可以使用兩個容器,一個用於維護順序,另一個用於提供快速查找,並使用謹慎的邏輯來保持順序一致。

+0

...或使用Boost.MultiIndex來爲您保持一致性。 – Angew 2014-09-18 17:28:40

+0

謝謝@MikeSeymour,這是一個徹底和可以理解的答案。我現在使用'std :: vector'。 – 2014-09-18 17:35:52

相關問題