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 :

question sur les unordered_map


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut question sur les unordered_map
    bonjour

    J'ai une question concernant les unordered_map. C'est très simple:
    je ne comprends pas pourquoi le code suivant ne retrouve pas dans la map l'élément correspondant à la clé "ddd".
    merci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     typedef std::unordered_map<const char*, int> Mymap; 
        Mymap c1;
        typedef Mymap::value_type type_sousjacent; 
        const char* u=new char[4];
    	u="ddd";
     
    	const char* w=new char[4];
    	w="edd";
     
        c1.insert(type_sousjacent("ddd", 1));
        c1.insert(type_sousjacent("edd", 1)); 
    	Mymap::key_type vv="ddd";
        Mymap::const_iterator it=c1.find(u);

    (EDIT:en fait j'ai compris, du moins, je pense, c'est un pb d'adresse).
    Mais je vois pas trop comment le résoudre

  2. #2
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Tu compares des pointeurs pas des chaines de caractères. La solution : introduit le bon prédicat. La meilleure solution, utilise des strings.

  3. #3
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    Le problème, c'est que si j'utilise un std::string:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        typedef std::unordered_map<std::string, int> Mymap; 
        Mymap c1;
        typedef Mymap::value_type type_sousjacent;
     std::string s="ddd";
    	 c1.insert(type_sousjacent(s, 1));
    j'obtiens comme erreur:


    Error 3 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const std::string' (or there is no acceptable conversion)

  4. #4
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Poste un code complet minimal compilable.. parce que là ce que tu montres y'a pas de soucis ...

  5. #5
    Membre éprouvé
    Inscrit en
    Novembre 2006
    Messages
    1 073
    Détails du profil
    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 073
    Par défaut
    héhé, ca marche j'avais oublié le #include<string>

    Mais en revanche, je veux utiliser le const char*.
    Comment puis-je faire pour qu'il n'y ait pas de comparaison de pointeurs, mais d'objets pointés?

    merci

  6. #6
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Il faut que tu fournisses la fonction de hash qui va bien de la même manière qu'il faut fournir un prédicat à une std::map.

    Une fonction de hash doit prendre en paramètre la clé et renvoyer un size_t.
    Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    struct HashCStringFunc
    {
       size_t operator()(const char* Key) const
       {
          size_t Val = 2166136261U;
          size_t First = 0;
          size_t Last = strlen(Key);
          size_t Stride = 1 + Last / 10;
     
          for(; First < Last; First += Stride)
             Val = 16777619U * Val ^ (size_t) Key[First];
          return (Val);
       }
    };
     
    int main()
    {
       typedef std::unordered_map<const char*, int, HashCStringFunc> HashCString;
       HashCString m;
     
       m["ddd"] = 1;
       m["edd"] =  1; 
       HashCString::const_iterator it = m.find("ddd");
    }
    Évidement la difficulté est de choisir une bonne fonction de hash bien adapté au problème, car c'est elle qui va conditionner les performances de la hashtable. Pour l'exemple ci-dessus, vu que j'y connais rien dans ce domaine, j'ai juste repris la fonction de hash prévu à la base pour les std::string dans les headers de la STL fourni avec VS2010 en remplaçant par des char*.

    HS :Au fait attention à ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
       const char* u=new char[4];
       u="ddd";
    C'est au mieux une fuite mémoire et au pire au segfault si tu fais un delete[] sur u, car u pointe maintenant sur la string-litteral "ddd".

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 637
    Par défaut
    Salut,
    Citation Envoyé par deubelte Voir le message
    héhé, ca marche j'avais oublié le #include<string>

    Mais en revanche, je veux utiliser le const char*.
    Comment puis-je faire pour qu'il n'y ait pas de comparaison de pointeurs, mais d'objets pointés?

    merci
    A vrai dire, la première question qui me vient à l'esprit, c'est "pourquoi "

    Il n'y a que des inconvénients à vouloir manipuler des pointeurs sur char au lieu de chaines de caractères:
    • Cela t'oblige à gérer "par toi même" la mémoire allouée à tes pointeurs.
    • Un pointeur n'est jamais... qu'une variable numérique représentant une adresse mémoire, même lorsqu'il s'agit d'un pointeur sur char, destiné à représenter une chaine de caractères "C style", et il faut donc utiliser les fonctions C de manipulation de chaines pour manipuler ces dernières "correctement"
    • Il est possible de convertir un pointeur sur char en std::string de manière totalement transparente
    • Il est possible de récupérer une chaine de caractères "C style" au départ d'une std::string
    • Etant donné que la chaine de caractères sert de clé, il n'est pas opportun de laisser quoi que ce soit la modifier, surtout si on la manipule sous la forme d'une chaine C style
    De plus, même si, pour une raison qui ne tient qu'à toi, tu venais à vouloir utiliser ton pointeur sur char sous la forme d'un... tableau de caractères (comprend: une succession de valeurs numérique comprises entre 0 et 255), il serait alors largement préférable d'utiliser un ... std::vector<char>, pour les même raisons (ou du moins celles qui sont applicables)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Petite question sur les performances de Postgres ...
    Par cb44 dans le forum PostgreSQL
    Réponses: 5
    Dernier message: 13/01/2004, 13h49
  2. question sur les vertex buffer et index buffer
    Par airseb dans le forum DirectX
    Réponses: 9
    Dernier message: 25/08/2003, 02h38
  3. question sur les variables globales et les thread posix
    Par souris_sonic dans le forum POSIX
    Réponses: 5
    Dernier message: 13/06/2003, 13h59
  4. Question sur les handles et les couleurs...
    Par MrDuChnok dans le forum C++Builder
    Réponses: 7
    Dernier message: 29/10/2002, 08h45
  5. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11

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