问题
I just found myself a little bit surprised being unable to simply use a
std::unordered_set<std::array<int, 16> > test;
because there does not seem to be a std::hash specialization for std::arrays. Why is that? Or did I simply not find it? If there is indeed none, can the following implementation attempt be simplified?
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;
}
};
}
I really feel this should somehow be part of the standard library.
回答1:
I'm not sure why the standard library hasn't included this, but Boost has hashing for all sorts of things made up from hashable types. The key function for this is hash_combine, which you are welcome to copy from boost/functional/hash/hash.hpp.
Using hash_combine, Boost derives a range_hash (just combining the hashes of a each element of a range), as well as pair and tuple hashers. The range_hash in turn can be used to hash any iterable container.
回答2:
Not an answer, but some useful information. The Feb draft of the C++11 standard specifies that std::hash is specialized for these types:
error_code§ 19.5.5bitset<N>§ 20.5.3unique_ptr<T, D>§ 20.7.2.36shared_ptr<T, D>§ 20.7.2.36type_index§ 20.13.4string§ 21.6u16string§ 21.6u32string§ 21.6wstring§ 21.6vector<bool, Allocator>§ 23.3.8thread::id§ 30.3.1.1
And all these types: § 20.8.12
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*>;
来源:https://stackoverflow.com/questions/8027368/are-there-no-specializations-of-stdhash-for-standard-containers