2013-06-28 1 views
1

J'ai une carte non ordonnée avec un type de clé _bstr_t. Donc, comme ce type de clé est pas prise en charge par la fonction de hachage par défaut, je définissais le foncteur:mappe non ordonnée avec fonction de hachage personnalisée (_bstr_t) fonctionne uniquement avec le constructeur par défaut (clés dupliquées)

struct KeyHash { 
    size_t operator()(const _bstr_t& key) const { 
     return hash<LPCTSTR>()(key); 
    } 
}; 

Next i défini typedef:

typedef unordered_map<_bstr_t, RecentInfo*, KeyHash> RecentInfoMap; 

Et problème il apparaît: si j'instancier RecentInfoMap avec constructeur par défaut

RecentMapInfo rim; 

alors tout fonctionne bien. Mais si je veux instancier RecentInfoMap avec le nombre initial de compartiments

RecentInfoMap rim(100); 

Ensuite, la carte ne fonctionne pas. Je ne peux pas obtenir de valeurs par ses clés. Aussi, si j'invoque rim.rehash (100) avant l'utilisation de la carte, cela ne fonctionne pas non plus.

Veuillez expliquer ce que je fais mal.

MIS À JOUR: quelques exemples de code:

unordered_map<bstr_t, int, KeyHash> map; 
_bstr_t t1("ORCL"); 
_bstr_t t2("ORCL"); 
map[t1] = 777; 
map[t2] = 555; 
fout << map[t1] << endl; 
fout << map[t2] << endl; 

Il y a tous OK: carte [t1] et carte des références [t2] à une valeur 555. Mais si la carte définie comme

unordered_map<bstr_t, int, KeyHash> map(100); 

Il y a ensuite des erreurs: map contient des clés dupliquées et mappe des références [t1] à 777 et des références à [55] carte à 555.

Cette instruction (avec invocation rehash) donne également des clés en double:

unordered_map<bstr_t, int, KeyHash> map; 
map.rehash(100); 
+2

Quelles sont les erreurs réelles que vous obtenez? – PlasmaHH

+0

Avec la carte constructeur par défaut, les valeurs ne sont pas renvoyées par ses clés. Comme si la paire clé-valeur ne se trouvait pas dans la carte. –

+0

poster un code montrant le problème avec la sortie réelle par rapport à la sortie attendue – rectummelancolique

Répondre

2

J'ai trouvé la solution. Juste écrit ma propre fonction de hachage personnalisée qui peut fonctionner avec des pointeurs char * (wchar_t *). Également ajouté foncteur d'égalité. Fonctionne bien pour moi. J'espère que cela sera utile à quelqu'un.

struct KeyHash { 
    size_t operator()(const _bstr_t& key) const { 
     LPCTSTR str = key; 
     LPCTSTR end = str + _tcslen(str); 
     size_t hash = 2166136261U; 
     while (str != end) { 
      hash = 16777619U * hash^static_cast<size_t>(*str++); 
     } 
     return hash; 
    } 
}; 


struct KeyEquals { 
    bool operator()(const _bstr_t& x, const _bstr_t& y) const { 
     return _tcscmp(x, y) == 0; 
    } 
}; 


typedef unordered_map<_bstr_t, RecentInfo*, KeyHash, KeyEquals> RecentInfoMap; 
1

Vous pouvez vérifier ce que KeyHash()(t1) et KeyHash()(t2) retour.

Il se peut que vous soyez très (dé) chanceux que cela fonctionne dans le premier cas. Bien que ce soit une sorte de tir dans le noir car je ne sais pas grand chose sur ces types de données Windows.

+0

J'ai vérifié il y a quelques minutes, vous avez raison - KeyHash renvoie différents résultats de hachage pour t1 et t2. Et je ne sais toujours pas pourquoi. –

+1

@EldarAgalarov Parce que VS2010 ne fournit pas un hachage 'char *' spécial, mais seulement la spécialisation partielle 'hash '. Il utilise ensuite en interne un hachage entier de la valeur du pointeur (et ne hache pas la chaîne elle-même), ce qui est conforme à la norme. – dyp

Questions connexes