std::hash
| Definiert in der Header-Datei <bitset> |
||
| Definiert in Header <coroutine> |
||
| Definiert in Header <chrono> |
(seit C++26) |
|
| Definiert in Header <filesystem> |
||
| Definiert in der Header-Datei <functional> |
||
| Definiert in Header <memory> |
||
| Definiert in der Header-Datei <optional> |
||
| Definiert in der Header-Datei <stacktrace> |
||
| Definiert in Header <string> |
||
| Definiert in Header <string_view> |
||
| Definiert in der Header-Datei <system_error> |
||
| Definiert in Header <text_encoding> |
||
| Definiert in Header <thread> |
||
| Definiert in Header <typeindex> |
||
| Definiert in der Header-Datei <variant> |
||
| Definiert in Header <vector> |
||
| template< class Key > struct hash; |
(seit C++11) | |
Die ungeordneten assoziativen Container std::unordered_set, std::unordered_multiset, std::unordered_map, std::unordered_multimap verwenden Spezialisierungen der Template-Klasse std::hash als Standard-Hashfunktion.
Gegeben einen Typ Key, ist jede Spezialisierung std::hash<Key> entweder *aktiviert* oder *deaktiviert*.
- Wenn
std::hash<Key>nicht vom Programm oder vom Benutzer bereitgestellt wird, ist sie deaktiviert. - Andernfalls ist
std::hash<Key>aktiviert, wenn alle folgenden Bedingungen erfüllt sind:
- Alle folgenden Anforderungen sind erfüllt:
- Hash (wobei
Keyder Typ des Funktionsaufrufarguments ist) - DefaultConstructible
- CopyAssignable
- Swappable
- Hash (wobei
- Gegeben die folgenden Werte:
- h, ein Objekt vom Typ
std::hash<Key>. - k1 und k2, Objekte vom Typ
Key.
- h, ein Objekt vom Typ
- Alle folgenden Anforderungen sind erfüllt:
- Wenn k1 == k2 true ist, dann ist auch h(k1) == h(k2) true.
- Sofern
std::hash<Key>keine programmdirekte Spezialisierung ist, wirft h(k1) niemals eine Ausnahme.
- Andernfalls ist
std::hash<Key>deaktiviert.
Deaktivierte Spezialisierungen erfüllen nicht die Anforderung Hash, erfüllen nicht die Anforderung FunctionObject, und die folgenden Werte sind alle 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
Mit anderen Worten, sie existieren, können aber nicht verwendet werden.
Verschachtelte Typen
|
(bis C++20) |
[bearbeiten] Memberfunktionen
| Erstellt ein Hash-Funktionsobjekt. (öffentliche Memberfunktion) | |
| Berechnet den Hash des Arguments. (öffentliche Memberfunktion) |
[bearbeiten] Standardbibliotheks-Spezialisierungen
Jeder Header, der die Template-Klasse std::hash deklariert, stellt auch aktivierte Spezialisierungen von std::hash für die folgenden Typen bereit:
- Alle cv-unqualifizierten arithmetischen Typen
- Alle cv-unqualifizierten Aufzählungstypen
- Alle cv-unqualifizierten Zeigertypen
- std::nullptr_t
Darüber hinaus stellen einige Header weitere aktivierte std::hash-Spezialisierungen für Bibliothekstypen bereit (siehe unten).
|
Für alle von der Standardbibliothek bereitgestellten
|
(seit C++17) |
[bearbeiten] Spezialisierungen für Bibliothekstypen
| Hash-Unterstützung für std::coroutine_handle (Klassentemplate-Spezialisierung) | |
| (C++11) |
Hash-Unterstützung für std::error_code (Klassentemplate-Spezialisierung) |
| Hash-Unterstützung für std::error_condition (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::stacktrace_entry (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::basic_stacktrace (class template specialization) | |
| (C++17) |
Hash-Unterstützung für std::optional (Klassentemplate-Spezialisierung) |
| (C++17) |
Hash-Unterstützung für std::variant (Klassentemplate-Spezialisierung) |
| (C++17) |
Hash-Unterstützung für std::monostate (Klassentemplate-Spezialisierung) |
| (C++11) |
Hash-Unterstützung für std::bitset (Klassentemplate-Spezialisierung) |
| (C++11) |
Hash-Unterstützung für std::unique_ptr (Klassentemplate-Spezialisierung) |
| (C++11) |
Hash-Unterstützung für std::shared_ptr (Klassentemplate-Spezialisierung) |
| (C++11) |
Hash-Unterstützung für std::type_index (Klassentemplate-Spezialisierung) |
| (C++11) |
Hash-Unterstützung für Strings (Klassentemplate-Spezialisierung) |
| Hash-Unterstützung für String-Views (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::text_encoding (Klassentemplate-Spezialisierung) | |
| (C++11) |
Hash-Unterstützung für std::vector<bool> (Klassentemplate-Spezialisierung) |
| Hash-Unterstützung für std::filesystem::path (Klassentemplate-Spezialisierung) | |
| (C++11) |
Hash-Unterstützung für std::thread::id (Klassentemplate-Spezialisierung) |
| Hash-Unterstützung für std::chrono::duration (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::time_point (Klassentemplate-Spezialisierung) | |
| (C++26) |
Hash-Unterstützung für std::chrono::day (Klassentemplate-Spezialisierung) |
| Hash-Unterstützung für std::chrono::month (Klassentemplate-Spezialisierung) | |
| (C++26) |
Hash-Unterstützung für std::chrono::year (Klassentemplate-Spezialisierung) |
| Hash-Unterstützung für std::chrono::weekday (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::weekday_indexed (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::weekday_last (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::month_day (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::month_day_last (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::month_weekday (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::month_weekday_last (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::year_month (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::year_month_day (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::year_month_day_last (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::year_month_weekday (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::year_month_weekday_last (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::zoned_time (Klassentemplate-Spezialisierung) | |
| Hash-Unterstützung für std::chrono::leap_second (Klassentemplate-Spezialisierung) |
[bearbeiten] Hinweise
Die tatsächlichen Hash-Funktionen sind implementierungsabhängig und müssen keine anderen Qualitätskriterien erfüllen als die oben genannten. Insbesondere verwenden einige Implementierungen triviale (identitätsbehaftete) Hash-Funktionen, die eine ganze Zahl auf sich selbst abbilden. Anders ausgedrückt: Diese Hash-Funktionen sind dafür ausgelegt, mit ungeordneten assoziativen Containern zu funktionieren, aber nicht beispielsweise als kryptografische Hashes.
Hash-Funktionen müssen nur innerhalb einer einzigen Programmausführung dasselbe Ergebnis für denselben Input liefern. Dies ermöglicht "gesalzene" Hashes, die Angriffe durch Kollisions-Denial-of-Service verhindern.
Es gibt keine Spezialisierung für C-Strings. std::hash<const char*> erzeugt einen Hash des Zeigerwerts (der Speicheradresse); er untersucht nicht den Inhalt eines Zeichenarrays.
Zusätzliche Spezialisierungen für std::pair und die Standard-Container-Typen sowie Hilfsfunktionen zum Kombinieren von Hashes sind in boost::hash verfügbar.
[bearbeiten] Beispiel
#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; // since C++20 }; // Before C++20. // 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()(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); // or use boost::hash_combine } }; // Custom specialization of std::hash can be injected in namespace 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); // or use 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"}; // Using the standalone function object. std::cout << "hash(" << std::quoted(obj.first_name) << ", " << std::quoted(obj.last_name) << ") =\t" << MyHash{}(obj) << " (using MyHash) or\n\t\t\t\t" << std::hash<S>{}(obj) << " (using injected specialization)\n"; // Custom hash makes it possible to use custom types in unordered containers. // The example will use the injected std::hash<S> specialization above, // to use MyHash instead, pass it as a second template argument. 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'; }
Mögliche Ausgabe
hash("Meet the new boss...") = 10656026664466977650
hash("Hubert", "Farnsworth") = 12922914235676820612 (using MyHash) or
12922914235676820612 (using injected specialization)
"Bender" "Rodriguez"
"Turanga" "Leela"
"Hubert" "Farnsworth"[bearbeiten] Fehlerberichte
Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.
| DR | angewendet auf | Verhalten wie veröffentlicht | Korrigiertes Verhalten |
|---|---|---|---|
| LWG 2119 | C++11 | Spezialisierungen für erweiterte Integer-Typen fehlten. | bereitgestellt |
| LWG 2148 | C++11 | Spezialisierungen für Aufzählungstypen fehlten. | bereitgestellt |
| LWG 2543 | C++11 | std::hash war möglicherweise nicht SFINAE-freundlich. |
Wurde SFINAE-freundlich gemacht. |
| LWG 2817 | C++11 | Spezialisierung für std::nullptr_t fehlte. | bereitgestellt |