std::hash
| Definido en el encabezado <bitset>
|
||
| Definido en el encabezado <coroutine>
|
||
| Definido en el encabezado <chrono>
|
(desde C++26) |
|
| Definido en el encabezado <filesystem>
|
||
| Definido en el encabezado <functional>
|
||
| Definido en el encabezado <memory>
|
||
| Definido en el encabezado <optional>
|
||
| Definido en el encabezado <stacktrace>
|
||
| Definido en el encabezado <string>
|
||
| Definido en el encabezado <string_view>
|
||
| Definido en el encabezado <system_error>
|
||
| Definido en el encabezado <text_encoding>
|
||
| Definido en el encabezado <thread>
|
||
| Definido en el encabezado <typeindex>
|
||
| Definido en el encabezado <variant>
|
||
| Definido en el encabezado <vector>
|
||
template< class Key >
struct hash;
|
(desde C++11) | |
Los contenedores asociativos no ordenados std::unordered_set, std::unordered_multiset, std::unordered_map, std::unordered_multimap usan especializaciones de la plantilla std::hash como función hash predeterminada.
Dado un tipo Key, cada especialización std::hash<Key> está habilitada o deshabilitada :
- Si
std::hash<Key>no es proporcionada por el programa o el usuario, está deshabilitada. - En caso contrario,
std::hash<Key>está habilitada si se cumplen todas las condiciones siguientes:
- Todos los requisitos siguientes se cumplen:
- Hash (con
Keycomo tipo de argumento de llamada a función) - DefaultConstructible
- CopyAssignable
- Swappable
- Hash (con
- Dados los siguientes valores:
h, un objeto de tipostd::hash<Key>.k1yk2, objetos de tipoKey.
- Todos los requisitos siguientes se cumplen:
- Si
k1 == k2estrue,h(k1) == h(k2)también estrue. - A menos que
std::hash<Key>sea una especialización definida por el programa,h(k1)nunca lanzará una excepción.
- Si
- En caso contrario,
std::hash<Key>está deshabilitada.
Las especializaciones deshabilitadas no cumplen Hash, no cumplen FunctionObject, y los siguientes valores son todos false:
std::is_default_constructible<std::hash<Key>>::valuestd::is_copy_constructible<std::hash<Key>>::valuestd::is_move_constructible<std::hash<Key>>::valuestd::is_copy_assignable<std::hash<Key>>::valuestd::is_move_assignable<std::hash<Key>>::value
En otras palabras, existen, pero no pueden ser utilizadas.
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 |