Forum Programmation.c++ STL : hash_set, utiliser une classe en paramètre

Posté par .
Tags : aucun
0
17
fév.
2009

Salut à tous.

J'ai une classe toute bête du genre :


template <>class T<> Couple
{
public :
...

private :
T x;
T y;
};



J'aimerai utiliser la class hash_set de la STL pour créer une ensemble de Couple.


je fais donc :


Couple c(1,2);//fonctionne
hash_set< Couple > set; //fonctionne
set.insert(c1); //FONCTIONNE PAS !!!


Pourquoi je n'arrive pas à ajouter mon objet c1 à l'ensemble set ???
J'ai également surchargé l'opérateur < et == de la classe Couple mais ça ne change rien ...
  • # Il manque quelque chose

    Posté par (page perso) . Évalué à 2.

    T'as un exemple ici: http://www.sgi.com/tech/stl/hash_set.html

    Tu n'as pas fourni d'indication sur la manière de calculer un hash à partir de ton objet, ni sur la manière de comparer deux hashes.

    À part ça, hash_set ne fait pas partie de la STL (=Standard Template Library).
    • [^] # Re: Il manque quelque chose

      Posté par (page perso) . Évalué à 1.

      Peut-être manque-t-il aussi le constructeur par recopie…
    • [^] # Re: Il manque quelque chose

      Posté par . Évalué à 3.

      hash_set est bien une extension STL qui vient historiquement de l'implémentation SGI (et qui a été reprise dans gcc et msvc).
      le namespace à utiliser est (compilo-dépendant) std ou std::ext ou stdext, etc.

      pour les différents paramètres template :
      hash_set<class _Value, class _HashFcn, class _EqualKey, class _Alloc>

      on a les paramètres par défaut suivant : _HashFcn = std::hash<_Value>, _EqualKey = std::equal_to<_Value> et _Alloc = std::alloc

      comme std::hash n'est pas instanciable (difficile de prévoir toutes les classes du monde en avance pour la fonction de hachage), il te reste à définir une classe foncteur que tu passes en paramètre en tant que classe de hachage pour Couple.

      Par contre, il n'est pas nécessaire de devoir comparer deux hashes (qui par définitions sont de type size_t) mais bien deux clés (et cela sera effectif par ta surcharge de l'opérator == appelé à travers std::equal_to).

      Enfin, l'opérateur < n'a rien à voir là dedans, il sert dans les set qui sont des structures ordonnées mais est inutile pour les containeurs non ordonnés que sont les hash_set et autres hash_map.

      Si le paramètre T de ton couple dispose d'une fonction de hash prédéfinie, tu peux utiliser quelque chose comme

      template <typename T>
      struct HashFn
      {
      const size_t operator()(const Couple<T>&c) const
      { return 13*hash(c.x) + 7*hash(c.y); }
      };

      exemple purement gratuit évidemment (je ne connais pas le pb plus en détail).

      tu appelles ensuite hash_set<Couple<T>, HashFn<T> >

      my 2 cents
      • [^] # Re: Il manque quelque chose

        Posté par . Évalué à 1.

        Ok merci beaucoup pour la description détaillée que tu as faite. Par contre, je viens d'essayer la méthode que tu décris et ça ne compile toujours pas. Voilà la source :


        template <class T >
        class Couple
        {
        public :
        Couple()
        {
        }
        private :
        T x;
        T y;
        };

        template <typename T>
        struct HashFn
        {
        const size_t operator()(const Couple&c) const
        { return 13; }
        };

        int main()
        {
        Couple c;
        hash_set<Couple, HashFn > set;
        set.insert(c);

        return 0;
        }

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.