Đối tượng hàm std::hash<>
được sử dụng.
Chuyên môn tiêu chuẩn tồn tại cho tất cả các loại được tích hợp và một số loại thư viện chuẩn khác chẳng hạn như std::string
và std::thread
. Xem liên kết để xem danh sách đầy đủ.
Đối với các loại khác được sử dụng trong std::unordered_map
, bạn sẽ phải chuyên std::hash<>
hoặc tạo đối tượng hàm của riêng bạn.
Nguy cơ va chạm hoàn toàn phụ thuộc vào thực thi, nhưng xem xét thực tế là số nguyên bị giới hạn giữa phạm vi được xác định, trong khi chuỗi dài về mặt lý thuyết, tôi cho rằng có cơ hội tốt hơn để va chạm với chuỗi.
Đối với việc thực hiện trong GCC, việc chuyên môn hóa cho kiểu dựng sẵn chỉ trả về mẫu bit. Dưới đây là cách thức chúng được quy định tại 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)
/// ...
Sự chuyên môn cho std::string
được định nghĩa là:
#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()); }
};
Một số tìm kiếm hơn nữa đưa chúng ta đến:
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
là một chức năng bên ngoài từ libstdc++
. Một chút: tìm kiếm này dẫn tôi đến this file, trong đó nêu:
// This file defines Hash_bytes, a primitive used for defining hash
// functions. Based on public domain MurmurHashUnaligned2, by Austin
// Appleby. http://murmurhash.googlepages.com/
Vì vậy, các thuật toán mặc định băm GCC sử dụng cho các chuỗi là MurmurHashUnaligned2.
Tôi nghĩ nó đạt tiêu chuẩn. Bạn không chắc chắn một unorderd_map là gì. – Joel
unordered_map giống như bảng băm ... Các hàm băm mặc định có thay đổi trong C++ 98 so với C++ 11 không? – Medicine
Bạn đã gắn thẻ C++ 11 này nhưng đã hỏi về TR1. Đó là nó? –