Namespaces
Variants

std:: hash

From cppreference.net
Utilities library
Défini dans l'en-tête <bitset>
Défini dans l'en-tête <coroutine>
(depuis C++20)
Défini dans l'en-tête <chrono>
(depuis C++26)
Défini dans l'en-tête <filesystem>
(depuis C++17)
Défini dans l'en-tête <functional>
Défini dans l'en-tête <memory>
Défini dans l'en-tête <optional>
(depuis C++17)
Défini dans l'en-tête <stacktrace>
(depuis C++23)
Défini dans l'en-tête <string>
Défini dans l'en-tête <string_view>
(depuis C++17)
Défini dans l'en-tête <system_error>
Défini dans l'en-tête <text_encoding>
(depuis C++26)
Défini dans l'en-tête <thread>
Défini dans l'en-tête <typeindex>
Défini dans l'en-tête <utility>
(depuis C++26)
Défini dans l'en-tête <variant>
(depuis C++17)
Défini dans l'en-tête <vector>
template < class Key >
struct hash ;
(depuis C++11)

Les spécialisations activées du modèle hash définissent un objet fonction qui implémente une fonction de hachage .

Étant donné un type Key , chaque spécialisation std::hash<Key> est soit activée soit désactivée  :

  • Si std::hash<Key> n'est pas fourni par le programme ou l'utilisateur, il est désactivé.
  • Sinon, std::hash<Key> est activé si toutes les conditions suivantes sont satisfaites :
  • Toutes les exigences suivantes sont satisfaites :
  • Étant donné les valeurs suivantes :
  • h , un objet de type std::hash<Key> .
  • k1 et k2 , des objets de type Key .
Toutes les exigences suivantes sont satisfaites :
  • Sinon, std::hash<Key> est désactivé.

Les spécialisations désactivées ne satisfont pas Hash , ne satisfont pas FunctionObject , et les valeurs suivantes sont toutes false :

En d'autres termes, ils existent, mais ne peuvent pas être utilisés.

Table des matières

Types imbriqués

Type Définition
argument_type (obsolète en C++17) Key
result_type (obsolète en C++17) std::size_t
(jusqu'à C++20)

Fonctions membres

construit un objet fonction de hachage
(fonction membre publique)
calcule le hachage de l'argument
(fonction membre publique)

Spécialisations de la bibliothèque standard

Chaque en-tête qui déclare le template std::hash fournit également des spécialisations activées de std::hash pour les types suivants :

Une implémentation autonome doit fournir ces spécialisations mentionnées précédemment et les spécialisations désactivées par défaut.

(since C++20)

En plus de cela, certains en-têtes fournissent également d'autres spécialisations activées std::hash pour les types de bibliothèque (voir ci-dessous ).

Pour toutes les spécialisations de std::hash fournies par la bibliothèque standard, à l'exception des suivantes, toutes leurs fonctions membres sont noexcept :

(depuis C++26)
(depuis C++17)

Spécialisations pour les types de bibliothèque

Bibliothèque de support du langage
prise en charge du hachage pour std::coroutine_handle
(spécialisation de modèle de classe)
Bibliothèque de diagnostic
Prise en charge du hachage pour std::error_code
(spécialisation de modèle de classe)
prise en charge du hachage pour std::error_condition
(spécialisation de modèle de classe)
Prise en charge du hachage pour std::type_index
(spécialisation de modèle de classe)
prise en charge du hachage pour std::stacktrace_entry
(spécialisation de modèle de classe)
Support de hachage pour std::basic_stacktrace
(spécialisation de modèle de classe)
Bibliothèque de gestion de la mémoire
Prise en charge du hachage pour std::unique_ptr
(spécialisation de modèle de classe)
prise en charge du hachage pour std::shared_ptr
(spécialisation de modèle de classe)
Support de hachage pour std::indirect
(spécialisation de modèle de classe)
Bibliothèque d'utilitaires généraux
prise en charge du hachage pour std::optional
(spécialisation de modèle de classe)
prise en charge du hachage pour std::variant
(spécialisation de modèle de classe)
prise en charge du hachage pour std::monostate
(spécialisation de modèle de classe)
prise en charge du hachage pour std::bitset
(spécialisation de modèle de classe)
Bibliothèque de conteneurs
prise en charge du hachage pour std::vector<bool>
(spécialisation de modèle de classe)
Bibliothèque de chaînes
prise en charge du hachage pour les chaînes de caractères
(spécialisation de modèle de classe)
prise en charge du hachage pour les vues de chaînes
(spécialisation de modèle de classe)
Bibliothèque de traitement de texte
Prise en charge du hachage pour std::text_encoding
(spécialisation de modèle de classe)
Bibliothèque de temps
prise en charge du hachage pour std::chrono::duration
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::time_point
(spécialisation de modèle de classe)
Support de hachage pour std::chrono::day
(spécialisation de modèle de classe)
Prise en charge du hachage pour std::chrono::month
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::year
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::weekday
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::weekday_indexed
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::weekday_last
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::month_day
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::month_day_last
(spécialisation de modèle de classe)
Prise en charge du hachage pour std::chrono::month_weekday
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::month_weekday_last
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::year_month
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::year_month_day
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::year_month_day_last
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::year_month_weekday
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::year_month_weekday_last
(spécialisation de modèle de classe)
Prise en charge du hachage pour std::chrono::zoned_time
(spécialisation de modèle de classe)
prise en charge du hachage pour std::chrono::leap_second
(spécialisation de modèle de classe)
Bibliothèque d'entrée/sortie
Support de hachage pour std::filesystem::path
(spécialisation de modèle de classe)
Bibliothèque de support de concurrence
Support de hachage pour std::thread::id
(spécialisation de modèle de classe)

Notes

Les fonctions de hachage réelles dépendent de l'implémentation et ne sont pas tenues de satisfaire à d'autres critères de qualité que ceux spécifiés ci-dessus. Notamment, certaines implémentations utilisent des fonctions de hachage triviales (identité) qui mappent un entier sur lui-même. En d'autres termes, ces fonctions de hachage sont conçues pour fonctionner avec des conteneurs associatifs non ordonnés, mais pas comme des hachages cryptographiques, par exemple.

Les fonctions de hachage sont seulement tenues de produire le même résultat pour la même entrée lors d'une seule exécution d'un programme ; cela permet des hachages salés qui préviennent les attaques par déni de service par collision.

Il n'y a pas de spécialisation pour les chaînes de caractères C. std :: hash < const char * > produit un hash de la valeur du pointeur (l'adresse mémoire), il n'examine pas le contenu d'aucun tableau de caractères.

Des spécialisations supplémentaires pour std::pair et les types de conteneurs standards, ainsi que des fonctions utilitaires pour composer des hachages sont disponibles dans boost::hash .

Exemple

#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; // depuis C++20
};
// Avant C++20.
// bool operator==(const S& lhs, const S& rhs)
// {
//     return lhs.first_name == rhs.first_name && lhs.last_name == rhs.last_name;
// }
// La fonction de hachage personnalisée peut être un objet fonction autonome.
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); // ou utiliser boost::hash_combine
    }
};
// La spécialisation personnalisée de std::hash peut être injectée dans l'espace de noms 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); // ou utiliser 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"};
    // Utilisation de l'objet fonction autonome.
    std::cout << "hash(" << std::quoted(obj.first_name) << ", "
              << std::quoted(obj.last_name) << ") =\t"
              << MyHash{}(obj) << " (en utilisant MyHash) ou\n\t\t\t\t"
              << std::hash<S>{}(obj) << " (en utilisant la spécialisation injectée)\n";
    // Le hachage personnalisé permet d'utiliser des types personnalisés dans les conteneurs non ordonnés.
    // L'exemple utilisera la spécialisation injectée std::hash<S> ci-dessus,
    // pour utiliser MyHash à la place, passez-le comme second argument template.
    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';
}

Sortie possible :

hash("Rencontrez le nouveau patron...") =  10656026664466977650
hash("Hubert", "Farnsworth") =  12922914235676820612 (en utilisant MyHash) ou
                                12922914235676820612 (en utilisant la spécialisation injectée)
"Bender" "Rodriguez"
"Turanga" "Leela"
"Hubert" "Farnsworth"

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement corrigé
LWG 2119 C++11 les spécialisations pour les types entiers étendus manquaient fournies
LWG 2148 C++11 les spécialisations pour les énumérations manquaient fournies
LWG 2543 C++11 std::hash pourrait ne pas être compatible SFINAE rendu compatible SFINAE
LWG 2817 C++11 la spécialisation pour std::nullptr_t manquait fournie