Если кто-то, как и я, наивно полагает, что std::hash<size_t>()(100) вернет 100, то разработчики стандартной библиотеки С++ в Майкрософт с ним не согласны и считают хеш так:
inline size_t _Hash_seq(const unsigned char *_First, size_t _Count)
{ // FNV-1a hash function for bytes in [_First, _First + _Count)
#if defined(_WIN64)
static_assert(sizeof(size_t) == 8, "This code is for 64-bit size_t.");
const size_t _FNV_offset_basis = 14695981039346656037ULL;
const size_t _FNV_prime = 1099511628211ULL;
#else /* defined(_WIN64) */
static_assert(sizeof(size_t) == 4, "This code is for 32-bit size_t.");
const size_t _FNV_offset_basis = 2166136261U;
const size_t _FNV_prime = 16777619U;
#endif /* defined(_WIN64) */
size_t _Val = _FNV_offset_basis;
for (size_t _Next = 0; _Next < _Count; ++_Next)
{ // fold in another byte
_Val ^= (size_t)_First[_Next];
_Val *= _FNV_prime;
}
return (_Val);
}
template<class _Kty>
struct _Bitwise_hash
{ // hash functor for plain old data
typedef _Kty argument_type;
typedef size_t result_type;
size_t operator()(const _Kty& _Keyval) const
{ // hash _Keyval to size_t value by pseudorandomizing transform
return (_Hash_seq((const unsigned char *)&_Keyval, sizeof (_Kty)));
}
};
template<>
struct hash<long long>
: public _Bitwise_hash<long long>
{ // hash functor for long long
};
Разработчики g++ лишены такой фантазии и тупо делают следующее:
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
template<> \
struct hash<_Tp> : public __hash_base<size_t, _Tp> \
{ \
size_t \
operator()(_Tp __val) const noexcept \
{ return static_cast<size_t>(__val); } \
};