2010-12-01 103 views
2

我一直在尋找unordered_set的構造函數。是不是可以使用自定義分配器實例構建unordered_set而不設置散列桶的數量?我真的寧願不要混淆實現細節,因爲我想要一個自定義分配器,而類型不提供默認值的定義。 MSDN只爲構造函數提供了三個重載,其中沒有一個非常有用。std :: unordered_set構造函數

編輯:聖潔的廢話。 std :: hash的STL實現不會專門用於具有自定義分配器類型的字符串 - 它只能執行顯式typedefs std :: string和std :: wstring。我的意思是,我可以理解不想嘗試散列隨機字符串,但僅僅因爲它有一個自定義分配器?這讓我厭惡。

tokens(std::unordered_set<string>().bucket_count(), std::hash<string>(), std::equal_to<string>(), stl_wrapper::hash_set<string>::allocator_type(this)) 
template<typename Char, typename CharTraits, typename Allocator> class std::hash<std::basic_string<Char, CharTraits, Allocator>> 
    : public std::unary_function<std::basic_string<Char, CharTraits, Allocator>, std::size_t> { 
public: 
    size_t operator()(const std::basic_string<Char, CharTraits, Allocator>& ref) const { 
     return std::hash<std::basic_string<Char, CharTraits>>()(std::basic_string<Char, CharTraits>(ref.begin(), ref.end())); 
    } 
}; 

解決了問題,但是多餘的構造和複製? Ewwwww。

+0

關於你的編輯:是的,很害怕。 `std :: hash`有點缺乏,特別是我認爲標準應該提供一個函數來散列一個字節序列,以使它更容易專門用於UDT(包括帶有自定義分配器的字符串)。但是,由於你的交替分配的字符串與任何授權的「散列」專業化無關,你是SOOL,看不到任何幫助。 AFAIK你只需選擇你自己的散列算法,然後寫一個專門化,或者指定散列到你的容器。 – 2010-12-01 17:32:24

+0

@Steve:不完全。 basic_string構造函數可以使用任何迭代器,因此將它擴展爲allocator不可知的實際並不是非常困難,但它涉及冗餘副本,這使我RAEG成爲可能。 – Puppy 2010-12-01 17:34:22

+0

@DeadMG:是的,這取決於你爲什麼使用自定義分配器。如果你希望程序中的所有分配都通過你的分配器,那麼它不僅僅是一個冗餘副本,而是完全失敗。 – 2010-12-01 17:36:27

回答

2

這很奇怪,但你是對的。我想這個想法是支持所有可能的參數組合,以及默認值。

我能想到處理這個問題的最好方法是使用所有默認設置構建一個空的unordered_set,使用unordered_set::bucket_count從它獲取默認桶數,然後在實例化實際需要的容器時將其用作輸入。

unordered_set<int> temp; 
size_t buckets = temp.bucket_count; 
unordered_set<string> actual(buckets, Hash(), Pred(), 
    YourAllocator(param1 /*, etc */)); 
0

既然你正在寫的Allocator,是有意義的控制桶的數量太多,畢竟兩者都是與內存相關的:)

史蒂夫給方法的心臟,如果你不想對,現在讓我提出一個輔助函數:)

template <typename T> 
size_t number_buckets() 
{ 
    std::unordered_set<T> useless; 
    return useless.bucket_count(); 
} 

有了這樣的,一點點(簡單的)助手:

template <typename T, typename Hash, typename Pred, typename Allocator> 
std::unordered_set<T,Hash,Pred,Allocator> 
    make_unordered_set(Hash const& hash, Pred const& pred, Allocator const& alloc) 
{ 
    static size_t const nbBuckets = number_buckets<T>(); 
    return std::unordered_set<T,Hash,Pred,Allocator>(nbBuckets, hash, pred, alloc); 
} 

工作得很好用auto

auto set = make_unordered_set<std::string>(Hash(), Pred(), Allocator(1,2,3)); 

你也可以,當然,只是淘汰定了你最喜歡的實現。

相關問題