2015-07-03 55 views
5

作爲一個練習,我試圖看看是否可以使用SFINAE爲std::pairstd::tuple創建一個std::hash專用化,但其所有模板參數均爲無符號類型。我有一些與他們的經驗,但從我所瞭解的哈希函數需要已被模板typename Enabled = void爲我添加專業化。我不確定該從哪裏出發。這是一個不起作用的嘗試。的std ::哈希專業化使用SFINAE?

#include <functional> 
#include <type_traits> 
#include <unordered_set> 
#include <utility> 

namespace std { 
template <typename T, typename Enabled = void> 
struct hash<std::pair<T, T>, std::enable_if_t<std::is_unsigned<T>::value>> 
{ 
    size_t operator()(const std::pair<T, T>& x) const 
    { 
     return x; 
    } 
}; 
}; // namespace std 


int 
main(int argc, char ** argv) 
{ 
    std::unordered_set<std::pair<unsigned, unsigned>> test{}; 
    return 0; 
} 

錯誤:

hash_sfinae.cpp:7:42: error: default template argument in a class template partial specialization 
template <typename T, typename Enabled = void> 
          ^
hash_sfinae.cpp:8:8: error: too many template arguments for class template 'hash' 
struct hash<std::pair<T, T>, std::enable_if_t<std::is_unsigned<T>::value>> 

這是關於我所期待的,因爲我想擴展模板參數散列...但我不知道的技術來處理這種情況呢。有人能幫助我理解嗎?

回答

9

對於不依賴於您自己定義的類型的類型,您不應專門針對std::hash

這就是說,這個技巧可能工作:

template<class T, class E> 
using first = T; 

template <typename T> 
struct hash<first<std::pair<T, T>, std::enable_if_t<std::is_unsigned<T>::value>>> 
{ 
    size_t operator()(const std::pair<T, T>& x) const 
    { 
     return x; 
    } 
}; 

真的,不過,不這樣做。寫你自己的哈希。

+0

有一個很好的理由不會爲對/元組「std :: hash」進行專門化:我真的希望很快就會在'std'中顯示一個自動合併散列。 – Yakk