Ответ 1
Используется объект функции std::hash<>
.
Стандартные специализации существуют для всех встроенных типов, а некоторые другие стандартные типы библиотек
таких как std::string
и std::thread
. См. Полный список ссылок.
Для других типов, которые будут использоваться в std::unordered_map
, вам придется специализироваться на std::hash<>
или создать свой собственный функциональный объект.
Вероятность столкновения полностью зависит от реализации, но учитывая тот факт, что целые числа ограничены между определенным диапазоном, а строки теоретически бесконечно длинны, я бы сказал, что вероятность столкновения со строками намного выше.
Что касается реализации в GCC, специализация для встроенных типов просто возвращает битовый шаблон. Здесь, как они определены в bits/functional_hash.h
:
/// Partial specializations for pointer types.
template<typename _Tp>
struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
{
size_t
operator()(_Tp* __p) const noexcept
{ return reinterpret_cast<size_t>(__p); }
};
// Explicit specializations for integer types.
#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); } \
};
/// Explicit specialization for bool.
_Cxx_hashtable_define_trivial_hash(bool)
/// Explicit specialization for char.
_Cxx_hashtable_define_trivial_hash(char)
/// ...
Специализация для std::string
определяется как:
#ifndef _GLIBCXX_COMPATIBILITY_CXX0X
/// std::hash specialization for string.
template<>
struct hash<string>
: public __hash_base<size_t, string>
{
size_t
operator()(const string& __s) const noexcept
{ return std::_Hash_impl::hash(__s.data(), __s.length()); }
};
Дальнейший поиск приводит нас к:
struct _Hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(0xc70f6907UL))
{ return _Hash_bytes(__ptr, __clength, __seed); }
...
};
...
// Hash function implementation for the nontrivial specialization.
// All of them are based on a primitive that hashes a pointer to a
// byte array. The actual hash algorithm is not guaranteed to stay
// the same from release to release -- it may be updated or tuned to
// improve hash quality or speed.
size_t
_Hash_bytes(const void* __ptr, size_t __len, size_t __seed);
_Hash_bytes
является внешней функцией из libstdc++
. Немного больше поиска привело меня к этому файлу, в котором говорится:
// This file defines Hash_bytes, a primitive used for defining hash
// functions. Based on public domain MurmurHashUnaligned2, by Austin
// Appleby. http://murmurhash.googlepages.com/
Таким образом, алгоритм хэширования по умолчанию, используемый GCC для строк, это MurmurHashUnaligned2.