g++ et hash_map<string, ...>

g++ et hash_map<string, ...> - C++ - Programmation

Marsh Posté le 27-01-2006 à 21:14:37    

Bonjour !
 
Lorsque l'on souhaite créer une hash_map dont les éléments clef sont de type string, cela ne fonctionne pas directement car il faut alors définir une fonction de hachage pour ce type. Par exemple, la spécialisation de la fonction hash<T> existante marche très bien :
 

Code :
  1. namespace __gnu_cxx {
  2.   template<> struct hash<std::string> {
  3.      size_t operator()(const std::string& x) const {
  4.        return hash<const char*>()(x.c_str());
  5.      }
  6.   };
  7. }


 
Mais par contre je n'arrive pas à faire fonctionner ceci (un bon paquet d'erreurs à la compilation) :
 

Code :
  1. struct HashString {
  2.   size_t operator()(const std::string& x) const {
  3.     return __gnu_cxx::hash<const char*>()(x.c_str());
  4.   }
  5. };
  6. ...
  7. hash_map<std::string, int, HashString()> m;
  8. ...


 
La question est donc : pourquoi ?

Reply

Marsh Posté le 27-01-2006 à 21:14:37   

Reply

Marsh Posté le 27-01-2006 à 21:20:05    

hash_map n'est pas standard; quelle implémentation utilises-tu ?

Reply

Marsh Posté le 27-01-2006 à 21:27:17    

_darkalt3_ a écrit :

hash_map n'est pas standard; quelle implémentation utilises-tu ?


 
Oui, hash_map n'est pas dans le standard, et en général la fonction de hash associée n'est fournie en extention que pour les types entiers primitifs et les chaines de caractères (char*). C'est le cas avec ce que j'utilise (g++). Par contre, c'est vrai que j'ai oublié de spécifier la version : 3.4.

Reply

Marsh Posté le 28-01-2006 à 13:05:56    

ash_map<std::string, int, HashString()> m;
 
 
 
c'est quoi ces parenthèses ?
 
 
et puis si t'as des string et que tu hash uniquement c_str(), tu risques de ne pas hacher le contenu réel de la chaine mais uniquement les premiers caractères.

Reply

Marsh Posté le 28-01-2006 à 16:03:01    

Taz a écrit :

ash_map<std::string, int, HashString()> m;
 
 
 
c'est quoi ces parenthèses ?
 


 
Effectivement, sans les parenthèses ça marche beaucoup mieux ! C'est vraiment une erreur bête, je ne sais pas pourquoi je tenais tant à passer une instance de l'objet fonction plutôt que le nom du type. Autant pour moi !
 

Taz a écrit :


et puis si t'as des string et que tu hash uniquement c_str(), tu risques de ne pas hacher le contenu réel de la chaine mais uniquement les premiers caractères.


 
Là en revanche je ne comprends pas trop pourquoi, la méthode c_str() est censée renvoyer un const char* pointant sur l'intégralité de la chaîne encapsulée (avec \0 rajouté à la fin pour l'occasion), même si pour cela (suivant l'implémentation) il lui faut au préalable copier la chaîne dans un nouveau tableau. Qu'est ce qui te fait dire que cela ne fonctionnerait pas, si on part du principe que hash<const char*> fait bien son travail ?

Reply

Marsh Posté le 28-01-2006 à 17:50:06    

tu passes rien du tout, il faut un paramètre template.
 
 
pour les strings : une string, ça peut contenir tout ce que tu veux, y compris des 0. une string n'est pas terminée par un 0. Donc si ta string vaut "a\0b"  c_str() ne te donnera que "a\0". En fait, strlen(s.c_str()) <= s.size()

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed