首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

std::hash

Defined in header <functional>

template< class Key > struct hash;

(since C++11)

Each specialization of this template is either enabled ("untainted") or disabled ("poisoned"). For every type Key for which neither the library nor the user provides an enabled specialization std::hash<Key>, that specialization exists and is disabled. Disabled specializations do not satisfy Hash, do not satisfy FunctionObject, and std::is_default_constructible_v, std::is_copy_constructible_v, std::is_move_constructible_v, std::is_copy_assignable_v, std::is_move_assignable_v are all false. In other words, they exist, but cannot be used.

(since C++17)

启用%28的专门化,因为C++17%29散列模板定义了实现散列函数此函数对象的实例满足Hash特别是,它们定义了operator()这一点:

  1. 接受类型的单个参数。Key...
  1. 返回类型的值。size_t表示参数的哈希值的。
  1. 调用时不会引发异常。
  1. 对于两个参数k1k2是平等的,std::hash<Key>()(k1) == std::hash<Key>()(k2)...
  1. 对于两个不同的参数k1k2不相等的概率std::hash<Key>()(k1) == std::hash<Key>()(k2)应该很小,接近1.0/std::numeric_limits<size_t>::max()...

的所有显式和部分专门化hash由标准库提供的DefaultConstructible,,,CopyAssignable,,,SwappableDestructible.用户提供的专门化hash还必须满足这些要求。

无序关联容器std::unordered_set,,,std::unordered_multiset,,,std::unordered_map,,,std::unordered_multimap使用模板的专门化std::hash作为默认的哈希函数。

注记

实际的哈希函数依赖于实现,除了上面指定的标准之外,不需要满足任何其他质量标准。值得注意的是,有些实现使用微不足道的%28标识%29散列函数将整数映射到自身。换句话说,这些散列函数设计用于处理无序关联容器,但不是加密散列。

Hash functions are only required to produce the same result for the same input within a single execution of a program; this allows salted hashes that prevent collision DoS attacks.

(since C++14)

C字符串没有专门化。std::hash<const char*>产生指针%28内存地址%29的值的散列,它不检查任何字符数组的内容。

成员类型

Member type

Definition

argument_type(deprecated in C++17)

Key

result_type(deprecated in C++17)

std::size_t

成员函数

(constructor)

constructs a hash function object (public member function)

operator()

calculate the hash of the argument (public member function)

基本类型的标准专门化

Defined in header <functional>

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*>;

In addition to the above, the standard library provides specializations for all (scoped and unscoped) enumeration types. These may be (but are not required to be) implemented as std::hash<std::underlying_type<Enum>::type>).

(since C++14)

Each standard library header that declares the template std::hash provides enabled specializations of std::hash for std::nullptr t and all cv-unqualified arithmetic types (including any extended integer types), all enumeration types, and all pointer types. All member functions of all standard library specializations of this template are noexcept except for the member functions of std::hash<std::optional>, std::hash<std::variant>, and std::hash<std::unique_ptr>

(since C++17)

库类型的标准专门化

std::hash<std::string>std::hash<std::u16string>std::hash<std::u32string>std::hash<std::wstring> (C++11)(C++11)(C++11)(C++11)

hash support for strings (class template specialization)

std::hash<std::error_code> (C++11)

hash support for std::error_code (class template specialization)

std::hash<std::bitset> (C++11)

hash support for std::bitset (class template specialization)

std::hash<std::unique_ptr> (C++11)

hash support for std::unique_ptr (class template specialization)

std::hash<std::shared_ptr> (C++11)

hash support for std::shared_ptr (class template specialization)

std::hash<std::type_index> (C++11)

hash support for std::type_index (class template specialization)

std::hash<std::vector<bool>> (C++11)

hash support for std::vector<bool> (class template specialization)

std::hash<std::thread::id> (C++11)

hash support for std::thread::id (class template specialization)

std::hash<std::optional> (C++17)

specializes the std::hash algorithm (class template specialization)

std::hash<std::variant> (C++17)

specializes the std::hash algorithm (class template specialization)

std::hash<std::string_view>std::hash<std::wstring_view>std::hash<std::u16string_view>std::hash<std::u32string_view> (C++17)

hash support for string views (class template specialization)

std::hash<std::error_condition> (C++17)

hash support for std::error_condition (class template specialization)

注:对std::pair和标准容器类型以及用于组合散列的实用程序函数都可以在布托...

二次

代码语言:javascript
复制
#include <iostream>
#include <iomanip>
#include <functional>
#include <string>
#include <unordered_set>
 
struct S {
    std::string first_name;
    std::string last_name;
};
bool operator==(const S& lhs, const S& rhs) {
    return lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name;
}
 
// custom hash can be a standalone function object:
struct MyHash
{
    std::size_t operator()(S const& s) const 
    {
        std::size_t h1 = std::hash<std::string>{}(s.first_name);
        std::size_t h2 = std::hash<std::string>{}(s.last_name);
        return h1 ^ (h2 << 1); // or use boost::hash_combine (see Discussion)
    }
};
 
// custom specialization of std::hash can be injected in namespace std
namespace std
{
    template<> struct hash<S>
    {
        typedef S argument_type;
        typedef std::size_t result_type;
        result_type operator()(argument_type const& s) const
        {
            result_type const h1 ( std::hash<std::string>{}(s.first_name) );
            result_type const h2 ( std::hash<std::string>{}(s.last_name) );
            return h1 ^ (h2 << 1); // or use boost::hash_combine (see Discussion)
        }
    };
}
 
int main()
{
 
    std::string str = "Meet the new boss...";
    std::size_t str_hash = std::hash<std::string>{}(str);
    std::cout << "hash(" << std::quoted(str) << ") = " << str_hash << '\n';
 
    S obj = { "Hubert", "Farnsworth"};
    // using the standalone function object
    std::cout << "hash(" << std::quoted(obj.first_name) << ',' 
               << std::quoted(obj.last_name) << ") = "
               << MyHash{}(obj) << " (using MyHash)\n                           or "
               << std::hash<S>{}(obj) << " (using std::hash) " << '\n';
 
    // custom hash makes it possible to use custom types in unordered containers
    // The example will use the injected std::hash specialization,
    // to use MyHash instead, pass it as a second template argument
    std::unordered_set<S> names = {obj, {"Bender", "Rodriguez"}, {"Leela", "Turanga"} };
    for(auto& s: names)
        std::cout << std::quoted(s.first_name) << ' ' << std::quoted(s.last_name) << '\n';
}

二次

可能的产出:

二次

代码语言:javascript
复制
hash("Meet the new boss...") = 1861821886482076440
hash("Hubert","Farnsworth") = 17622465712001802105 (using MyHash)
                           or 17622465712001802105 (using std::hash) 
"Leela" "Turanga"
"Bender" "Rodriguez"
"Hubert" "Farnsworth"

二次

代码语言:txt
复制
 © cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券