std:: hash
|
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:
-
-
Hash
(con
Keycomo tipo de argumento de llamada de función) - DefaultConstructible
- CopyAssignable
- Swappable
-
Hash
(con
- Dados los siguientes valores:
-
-
h
, un objeto de tipo
std::hash<Key>. -
k1
y
k2
, objetos de tipo
Key.
-
h
, un objeto de tipo
-
Se satisfacen todos los siguientes requisitos:
- Si k1 == k2 es true , h ( k1 ) == h ( k2 ) también es true .
-
A menos que
std::hash<Key>sea una especialización definida por el programa , h ( k1 ) nunca lanzará una excepción.
-
De lo contrario,
std::hash<Key>está deshabilitado.
Las especializaciones deshabilitadas no satisfacen Hash , no satisfacen FunctionObject , y los siguientes valores son todos false :
- std:: is_default_constructible < std :: hash < Key >> :: value
- std:: is_copy_constructible < std :: hash < Key >> :: value
- std:: is_move_constructible < std :: hash < Key >> :: value
- std:: is_copy_assignable < std :: hash < Key >> :: value
- std:: is_move_assignable < std :: hash < Key >> :: value
En otras palabras, existen, pero no pueden utilizarse.
Tipos anidados
|
(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:
- todos los tipos aritméticos sin calificadores cv
- todos los tipos de enumeración sin calificadores cv
- todos los tipos de puntero sin calificadores cv
- std::nullptr_t
|
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
|
(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 |
|
|
(C++11)
|
soporte de hash para
std::error_code
(especialización de plantilla de clase) |
|
(C++17)
|
soporte de hash para
std::error_condition
(especialización de plantilla de clase) |
|
(C++11)
|
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 |
|
|
(C++11)
|
soporte de hash para
std::unique_ptr
(especialización de plantilla de clase) |
|
(C++11)
|
soporte de hash para
std::shared_ptr
(especialización de plantilla de clase) |
|
(C++26)
|
soporte de hash para
std::indirect
(especialización de plantilla de clase) |
Biblioteca de utilidades generales |
|
|
(C++17)
|
soporte de hash para
std::optional
(especialización de plantilla de clase) |
|
(C++17)
|
soporte de hash para
std::variant
(especialización de plantilla de clase) |
|
(C++17)
|
soporte de hash para
std::monostate
(especialización de plantilla de clase) |
|
(C++11)
|
soporte de hash para
std::bitset
(especialización de plantilla de clase) |
Biblioteca de contenedores |
|
|
(C++11)
|
soporte de hash para
std::vector<bool>
(especialización de plantilla de clase) |
Biblioteca de cadenas |
|
|
(C++11)
|
soporte de hash para cadenas
(especialización de plantilla de clase) |
|
(C++17)
(C++17)
(C++20)
(C++17)
(C++17)
|
soporte de hash para vistas de cadena
(especialización de plantilla de clase) |
Biblioteca de procesamiento de texto |
|
|
(C++26)
|
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) |
|
|
(C++26)
|
soporte de hash para
std::chrono::day
(especialización de plantilla de clase) |
|
(C++26)
|
soporte de hash para
std::chrono::month
(especialización de plantilla de clase) |
|
(C++26)
|
soporte de hash para
std::chrono::year
(especialización de plantilla de clase) |
|
(C++26)
|
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 |
|
|
(C++11)
|
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 |