Namensräume
Varianten
Aktionen

std::hash

Von cppreference.com
< cpp‎ | utility
 
 
Dienstprogramm-Bibliotheken
Sprachunterstützung
Typunterstützung (Basistypen, RTTI)
Bibliotheks-Feature-Test-Makros (C++20)
Programm-Dienstprogramme
Variadische Funktionen
Coroutine-Unterstützung (C++20)
Vertragsunterstützung (C++26)
Drei-Wege-Vergleich
(C++20)
(C++20)(C++20)(C++20)  
(C++20)(C++20)(C++20)

Allgemeine Hilfsmittel
Relationale Operatoren (in C++20 veraltet)
 
 
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:
  • Gegeben die folgenden Werte:
  • h, ein Objekt vom Typ std::hash<Key>.
  • k1 und k2, Objekte vom Typ Key.
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:

Mit anderen Worten, sie existieren, können aber nicht verwendet werden.

Inhalt

Verschachtelte Typen

Name Definition
argument_type (veraltet in C++17) Key
result_type (veraltet in C++17) std::size_t
(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:

Darüber hinaus stellen einige Header weitere aktivierte std::hash-Spezialisierungen für Bibliothekstypen bereit (siehe unten).

Für alle von der Standardbibliothek bereitgestellten std::hash-Spezialisierungen, mit Ausnahme der folgenden, sind alle ihre Memberfunktionen noexcept:

(seit C++26)
(seit C++17)

[bearbeiten] Spezialisierungen für Bibliothekstypen

Hash-Unterstützung für std::coroutine_handle
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::error_code
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::error_condition
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::stacktrace_entry
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::basic_stacktrace
(class template specialization) [edit]
Hash-Unterstützung für std::optional
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::variant
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::monostate
(Klassentemplate-Spezialisierung)
Hash-Unterstützung für std::bitset
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::unique_ptr
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::shared_ptr
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::type_index
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für Strings
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für String-Views
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::text_encoding
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::vector<bool>
(Klassentemplate-Spezialisierung)
Hash-Unterstützung für std::filesystem::path
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::thread::id
(Klassentemplate-Spezialisierung) [bearbeiten]
Hash-Unterstützung für std::chrono::duration
(Klassentemplate-Spezialisierung)
Hash-Unterstützung für std::chrono::time_point
(Klassentemplate-Spezialisierung)
Hash-Unterstützung für std::chrono::day
(Klassentemplate-Spezialisierung)
Hash-Unterstützung für std::chrono::month
(Klassentemplate-Spezialisierung)
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