Namespaces
Variants

std:: hash

From cppreference.net
Utilities library
Definido en el encabezado <bitset>
Definido en el encabezado <coroutine>
(desde C++20)
Definido en el encabezado <chrono>
(desde C++26)
Definido en el encabezado <filesystem>
(desde C++17)
Definido en el encabezado <functional>
Definido en el encabezado <memory>
Definido en el encabezado <optional>
(desde C++17)
Definido en el encabezado <stacktrace>
(desde C++23)
Definido en el encabezado <string>
Definido en el encabezado <string_view>
(desde C++17)
Definido en el encabezado <system_error>
Definido en el encabezado <text_encoding>
(desde C++26)
Definido en el encabezado <thread>
Definido en el encabezado <typeindex>
Definido en el encabezado <utility>
(desde C++26)
Definido en el encabezado <variant>
(desde C++17)
Definido en el encabezado <vector>
template < class Key >
struct hash ;
(desde C++11)

Las especializaciones habilitadas de la plantilla hash definen un objeto función que implementa una función hash .

Dado un tipo Key , cada especialización std::hash<Key> está habilitada o deshabilitada :

  • Si std::hash<Key> no es proporcionado por el programa o el usuario, está deshabilitado.
  • De lo contrario, std::hash<Key> está habilitado si se cumplen todas las siguientes condiciones:
  • Se satisfacen todos los siguientes requisitos:
  • Dados los siguientes valores:
  • h , un objeto de tipo std::hash<Key> .
  • k1 y k2 , objetos de tipo Key .
Se satisfacen todos los siguientes requisitos:
  • De lo contrario, std::hash<Key> está deshabilitado.

Las especializaciones deshabilitadas no satisfacen Hash , no satisfacen FunctionObject , y los siguientes valores son todos false :

**Nota:** Todo el contenido dentro de las etiquetas ` ` se ha preservado sin traducción ya que contiene código C++ y términos específicos que no deben traducirse, de acuerdo con las instrucciones proporcionadas.

En otras palabras, existen, pero no pueden utilizarse.

Contenidos

Tipos anidados

Tipo Definición
argument_type (obsoleto en C++17) Key
result_type (obsoleto en C++17) std::size_t
(hasta C++20)

Funciones miembro

construye un objeto de función hash
(función miembro pública)
calcula el hash del argumento
(función miembro pública)

Especializaciones de la biblioteca estándar

Cada encabezado que declara la plantilla std::hash también proporciona especializaciones habilitadas de std::hash para los siguientes tipos:

Una implementación independiente debe proporcionar estas especializaciones mencionadas anteriormente y las especializaciones deshabilitadas por defecto.

(since C++20)

Además de eso, algunos encabezados también proporcionan otras especializaciones habilitadas std::hash para tipos de biblioteca (ver abajo ).

Para todas las especializaciones de std::hash proporcionadas por la biblioteca estándar, excepto las siguientes, todas sus funciones miembro son noexcept :

(desde C++26)
(desde C++17)

Especializaciones para tipos de biblioteca

Biblioteca de soporte del lenguaje
soporte de hash para std::coroutine_handle
(especialización de plantilla de clase)
Biblioteca de Diagnósticos
soporte de hash para std::error_code
(especialización de plantilla de clase)
soporte de hash para std::error_condition
(especialización de plantilla de clase)
Soporte de hash para std::type_index
(especialización de plantilla de clase)
soporte de hash para std::stacktrace_entry
(especialización de plantilla de clase)
soporte de hash para std::basic_stacktrace
(especialización de plantilla de clase)
Biblioteca de gestión de memoria
soporte de hash para std::unique_ptr
(especialización de plantilla de clase)
soporte de hash para std::shared_ptr
(especialización de plantilla de clase)
soporte de hash para std::indirect
(especialización de plantilla de clase)
Biblioteca de utilidades generales
soporte de hash para std::optional
(especialización de plantilla de clase)
soporte de hash para std::variant
(especialización de plantilla de clase)
soporte de hash para std::monostate
(especialización de plantilla de clase)
soporte de hash para std::bitset
(especialización de plantilla de clase)
Biblioteca de contenedores
soporte de hash para std::vector<bool>
(especialización de plantilla de clase)
Biblioteca de cadenas
soporte de hash para cadenas
(especialización de plantilla de clase)
soporte de hash para vistas de cadena
(especialización de plantilla de clase)
Biblioteca de procesamiento de texto
soporte de hash para std::text_encoding
(especialización de plantilla de clase)
Biblioteca de Tiempo
soporte de hash para std::chrono::duration
(especialización de plantilla de clase)
soporte de hash para std::chrono::time_point
(especialización de plantilla de clase)
soporte de hash para std::chrono::day
(especialización de plantilla de clase)
soporte de hash para std::chrono::month
(especialización de plantilla de clase)
soporte de hash para std::chrono::year
(especialización de plantilla de clase)
soporte de hash para std::chrono::weekday
(especialización de plantilla de clase)
soporte de hash para std::chrono::weekday_indexed
(especialización de plantilla de clase)
soporte de hash para std::chrono::weekday_last
(especialización de plantilla de clase)
soporte de hash para std::chrono::month_day
(especialización de plantilla de clase)
soporte de hash para std::chrono::month_day_last
(especialización de plantilla de clase)
soporte de hash para std::chrono::month_weekday
(especialización de plantilla de clase)
soporte de hash para std::chrono::month_weekday_last
(especialización de plantilla de clase)
soporte de hash para std::chrono::year_month
(especialización de plantilla de clase)
soporte de hash para std::chrono::year_month_day
(especialización de plantilla de clase)
soporte de hash para std::chrono::year_month_day_last
(especialización de plantilla de clase)
soporte de hash para std::chrono::year_month_weekday
(especialización de plantilla de clase)
soporte de hash para std::chrono::year_month_weekday_last
(especialización de plantilla de clase)
soporte de hash para std::chrono::zoned_time
(especialización de plantilla de clase)
soporte de hash para std::chrono::leap_second
(especialización de plantilla de clase)
Biblioteca de entrada/salida
Soporte de hash para std::filesystem::path
(especialización de plantilla de clase)
Biblioteca de soporte para concurrencia
Soporte de hash para std::thread::id
(especialización de plantilla de clase)

Notas

Las funciones hash reales dependen de la implementación y no están obligadas a cumplir ningún otro criterio de calidad excepto los especificados anteriormente. Cabe destacar que algunas implementaciones utilizan funciones hash triviales (identidad) que mapean un entero a sí mismo. En otras palabras, estas funciones hash están diseñadas para funcionar con contenedores asociativos no ordenados, pero no como hashes criptográficos, por ejemplo.

Las funciones hash solo están obligadas a producir el mismo resultado para la misma entrada dentro de una única ejecución de un programa; esto permite hashes con sal que previenen ataques de denegación de servicio por colisión.

No existe una especialización para cadenas C. std :: hash < const char * > produce un hash del valor del puntero (la dirección de memoria), no examina el contenido de ningún arreglo de caracteres.

Especializaciones adicionales para std::pair y los tipos de contenedores estándar, así como funciones de utilidad para componer hashes están disponibles en boost::hash .

Ejemplo

#include <cstddef>
#include <functional>
#include <iomanip>
#include <iostream>
#include <string>
#include <unordered_set>
struct S
{
    std::string first_name;
    std::string last_name;
    bool operator==(const S&) const = default; // desde C++20
};
// Antes de C++20.
// bool operator==(const S& lhs, const S& rhs)
// {
//     return lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name;
// }
// El hash personalizado puede ser un objeto función independiente.
struct MyHash
{
    std::size_t operator()(const S& s) const noexcept
    {
        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); // o usar boost::hash_combine
    }
};
// La especialización personalizada de std::hash puede inyectarse en el espacio de nombres std.
template<>
struct std::hash<S>
{
    std::size_t operator()(const S& s) const noexcept
    {
        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); // o usar boost::hash_combine
    }
};
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) << ") =\t" << str_hash << '\n';
    S obj = {"Hubert", "Farnsworth"};
    // Usando el objeto función independiente.
    std::cout << "hash(" << std::quoted(obj.first_name) << ", "
              << std::quoted(obj.last_name) << ") =\t"
              << MyHash{}(obj) << " (usando MyHash) o\n\t\t\t\t"
              << std::hash<S>{}(obj) << " (usando especialización inyectada)\n";
    // El hash personalizado permite usar tipos personalizados en contenedores desordenados.
    // El ejemplo usará la especialización inyectada std::hash<S> anterior,
    // para usar MyHash en su lugar, páselo como segundo argumento de plantilla.
    std::unordered_set<S> names = {obj, {"Bender", "Rodriguez"}, {"Turanga", "Leela"}};
    for (auto const& s: names)
        std::cout << std::quoted(s.first_name) << ' '
                  << std::quoted(s.last_name) << '\n';
}

Salida posible:

hash("Conoce al nuevo jefe...") =  10656026664466977650
hash("Hubert", "Farnsworth") =  12922914235676820612 (usando MyHash) o
                                12922914235676820612 (usando especialización inyectada)
"Bender" "Rodriguez"
"Turanga" "Leela"
"Hubert" "Farnsworth"

Informes de defectos

Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares de C++ publicados anteriormente.

DR Aplicado a Comportamiento publicado Comportamiento correcto
LWG 2119 C++11 faltaban especializaciones para tipos enteros extendidos proporcionadas
LWG 2148 C++11 faltaban especializaciones para enumeraciones proporcionadas
LWG 2543 C++11 std::hash podría no ser compatible con SFINAE hecho compatible con SFINAE
LWG 2817 C++11 faltaba especialización para std::nullptr_t proporcionada