IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

std::unordered_set et std::hash


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Par défaut std::unordered_set et std::hash
    Bonjour,

    je souhaite créer une classe 'Ensemble' qui hérite de 'std::unordered_set' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T>
    class Ensemble : public std::unordered_set<T> {
        ...
    }
    J'ai plusieurs classe qui hérite de la classe 'Element' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class A : public Element { ... }
    class B : public Element { ... }
    J'ai défini la fonction de Hashage pour 'Element' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace std {
        template <>
        struct hash<Element> {
            size_t operator()(const Element & e) const noexcept {
                return e.getId(); // Unique Id
            }
        };
    }
    Le problème c'est que je ne parviens pas à faire des ensemble de A ou B :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main() {
        Ensemble<Element> mySet_1; // Ok  
        Ensemble<A> mySet_2; // Pas Ok
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    error: no match for call to '(const std::hash<A>) (const A&)'|
    Quelqu'un peut-il m'expliquer le fonctionnement de std::hash ? Ou est l'erreur ? Merci.

  2. #2
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Salut!

    Pour commencer, les conteneurs de la STL ne sont pas fait pour faire partie d'un héritage (tu verras qu'il n'y a aucune fonction membre virtuelle dans ces classes).
    Je te conseille donc de mettre ton std::unordered_set en tant que membre de ta classe Ensemble, quitte à forwarder les fonctions dont tu as besoin (begin, end, find, insert...).

    Ensuite, pour ton problème, tu as défini un hash pour Element, mais pas pour A.
    Tu remarqueras qu'il te demande bien un std::hash< A >, cela ne tient pas compte de l'héritage que tu as mis en place.
    Tu peux le définir comme ceci, en utilisant ton std::hash< Element >:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    namespace std {
        template <>
        struct hash<A> {
            size_t operator()(const A & a) const noexcept {
                return hash<Element>()( a );
            }
        };
    }
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  3. #3
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    Ensuite, pour ton problème, tu as défini un hash pour Element, mais pas pour A.
    Tu remarqueras qu'il te demande bien un std::hash< A >, cela ne tient pas compte de l'héritage que tu as mis en place.
    [/code]
    Oui j'ai bien compris. Mon but est de ne pas définir hash pour chaque classe : A, B, ... C'est pour cela que j'ai créé la classe Element. Comment faire ?

    En quoi l'héritage pose problème. J'ai besoin d'un objet std::unordered_set avec des méthodes supplémentaires ... je n'ai pas le choix, non ?

  4. #4
    Membre très actif
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    538
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 538
    Par défaut
    Est-ce correct comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct HashElement {
        size_t operator() (const Element & e) const {
           return e.getId();
        }
    };
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    template<class T>
    class Ensemble : public std::unordered_set<T, HashElement> {
    ...
    }

  5. #5
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    A part pour l'héritage, oui.
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par dragonjoker59 Voir le message
    A part pour l'héritage, oui.
    Quel est le problème avec cet héritage, s'il ne fait pas de polymorphisme ?

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Salut,

    bah l'erreur, le compilateur te l'indique, error: no match for call to '(const std::hash<A>) (const A&)'| que ne comprends-tu pas ?
    Il n'existe aucune fonction std::hash<A>.. et pourquoi faire un héritage de std::unordered_set ? C'est peu commun et peu recommandé.
    De même que ta façon d'utiliser un std::unordered_set. Il existe un paramètre template pour définir sa fonction de hash, pas besoin de spécialiser le paramètre par défaut fourni par la std.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

Discussions similaires

  1. la difference entre deux std::unordered_set
    Par mohsenuss91 dans le forum C++
    Réponses: 7
    Dernier message: 21/04/2015, 17h30
  2. Équivalent de std::min et std::max en C?
    Par vdumont dans le forum C
    Réponses: 2
    Dernier message: 08/10/2006, 18h15
  3. conversion std::string en std::istringstream
    Par flipper203 dans le forum SL & STL
    Réponses: 3
    Dernier message: 06/07/2006, 18h34
  4. std::cout et std::wstring
    Par glKabuto dans le forum SL & STL
    Réponses: 11
    Dernier message: 10/06/2006, 18h44
  5. std::sort() sur std::vector()
    Par tut dans le forum SL & STL
    Réponses: 20
    Dernier message: 05/01/2005, 19h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo