2011-11-06 57 views
22

just發現自己有點吃驚暫時無法簡單地用一個標準容器是否沒有針對std :: hash的特化?

std::unordered_set<std::array<int, 16> > test; 

,因爲似乎沒有成爲一個std::hash專業化爲std::array秒。這是爲什麼?或者我根本找不到它?如果確實沒有,下面的實現嘗試可以簡化嗎?

namespace std 
{ 
    template<typename T, size_t N> 
    struct hash<array<T, N> > 
    { 
     typedef array<T, N> argument_type; 
     typedef size_t result_type; 

     result_type operator()(const argument_type& a) const 
     { 
      hash<T> hasher; 
      result_type h = 0; 
      for (result_type i = 0; i < N; ++i) 
      { 
       h = h * 31 + hasher(a[i]); 
      } 
      return h; 
     } 
    }; 
} 

我真的覺得這應該以某種方式成爲標準庫的一部分。

+3

真的沒有一個,只有'std :: string'和朋友都有這個特權。如果我說這是因爲C++在標準數據結構方面拖延到現有技術水平的努力還沒有完成整個工作,我會不會真的不受歡迎?實際上,模板沒有任何必需的'hash'特性(並且這又會要求它們的模板參數可哈希)。唯一需要的特化是內置類型和四個具體的字符串類。所以我懷疑那裏畫了一條線。 –

+0

@Steve:哪4個具體的字符串類? – fredoverflow

+2

'string','u16string','u32string','wstring'(21.6在C++ 11中)。我認爲'pair'和'tuple'應該是次最高優先級的目標,接下來是標準容器,後面是由可哈希成員組成的任何聚合類型的默認哈希。 –

回答

11

我不知道爲什麼標準庫沒有包含這個,但Boost對由可哈希類型組成的各種東西進行哈希處理。關鍵功能是hash_combine,歡迎您從boost/functional/hash/hash.hpp複製。

使用hash_combine,Boost得到range_hash(只是將一個範圍內的每個元素的散列組合起來),以及對和元組哈希函數。 range_hash反過來可以用來散列任何可迭代的容器。

+8

是的,'range_hash'聽起來應該是標準的。 – fredoverflow

11

不是答案,而是一些有用的信息。在C++ 11標準的草案二月指定std::hash是專門爲這些類型:

  • error_code§19.5.5
  • bitset<N>§20.5.3
  • unique_ptr<T, D>§20.7.2.36
  • shared_ptr<T, D> §20.7.2.36
  • type_index§20.13.4
  • string§21.6
  • u16string§21.6
  • u32string§21.6
  • wstring§21.6
  • vector<bool, Allocator>§23.3.8
  • thread::id§30.3.1.1

而且所有這些類型:§12年8月20日

template <> struct hash<bool>; 
template <> struct hash<char>; 
template <> struct hash<signed char>; 
template <> struct hash<unsigned char>; 
template <> struct hash<char16_t>; 
template <> struct hash<char32_t>; 
template <> struct hash<wchar_t>; 
template <> struct hash<short>; 
template <> struct hash<unsigned short>; 
template <> struct hash<int>; 
template <> struct hash<unsigned int>; 
template <> struct hash<long>; 
template <> struct hash<long long>; 
template <> struct hash<unsigned long>; 
template <> struct hash<unsigned long long>; 
template <> struct hash<float>; 
template <> struct hash<double>; 
template <> struct hash<long double>; 
template<class T> struct hash<T*>; 
相關問題