2015-07-03 42 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