C++ unordered_map avec char* comme clé

Je suis épuisé lorsque vous essayez d'utiliser le conteneur unordered_map avec char* comme la clé (sur Windows, je suis avec VS 2010). Je sais que je dois définir mon propre fonction de comparaison pour char*, qui hérite de l' binary_function. Ce qui suit est un exemple de programme.

#include<unordered_map>
#include <iostream>
#include <string>
using namespace std;

template <class _Tp>  
struct my_equal_to : public binary_function<_Tp, _Tp, bool>  
{  
    bool operator()(const _Tp& __x, const _Tp& __y) const  
    { return strcmp( __x, __y ) == 0; }  
};

typedef unordered_map<char*, unsigned int, ::std::tr1::hash<char*>,  my_equal_to<char*> > my_unordered_map;
//typedef unordered_map<string, unsigned int > my_unordered_map;

my_unordered_map location_map;

int main(){
    char a[10] = "ab";
    location_map.insert(my_unordered_map::value_type(a, 10));
    char b[10] = "abc";
    location_map.insert(my_unordered_map::value_type(b, 20));

    char c[10] = "abc";
    location_map.insert(my_unordered_map::value_type(c, 20));

    printf("map size: %d\n", location_map.size());
    my_unordered_map::iterator it;
    if ((it = location_map.find("abc")) != location_map.end())
    {
        printf("found!\n");
    }

    return 0;
} 

Je insérer de la même chaîne C abc deux fois et de le regarder. La deuxième insertion doit échouer et il n'y aura qu'un seul abc dans le unordered_map. Cependant, la taille de la sortie est de 3. Il semble que la fonction de comparaison ne fonctionne pas correctement ici.

En outre, je reçois un autre résultat étrange à propos de la find fonction, par l'exécution du programme, à plusieurs reprises, la constatation du résultat de change même! Parfois, la chaîne abc se trouve, alors que les autres fois abc n'est pas trouvé!!!

Quelqu'un pourrait-il m'aider sur ce point? Votre aide est grandement appréciée!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Edit: d'Après la définition d'une fonction de hachage pour char* par ma propre, le programme fonctionne correctement. Le programme complet de code est indiqué ci-dessous. Merci à vous tous.

#include<unordered_map>
#include <iostream>
using namespace std;

template <class _Tp>  
struct my_equal_to : public binary_function<_Tp, _Tp, bool>  
{  
    bool operator()(const _Tp& __x, const _Tp& __y) const  
    { return strcmp( __x, __y ) == 0; }  
};


struct Hash_Func{
    //BKDR hash algorithm
    int operator()(char * str)const
    {
        int seed = 131;//31  131 1313 13131131313 etc//
        int hash = 0;
        while(*str)
        {
            hash = (hash * seed) + (*str);
            str ++;
        }

        return hash & (0x7FFFFFFF);
    }
};

typedef unordered_map<char*, unsigned int, Hash_Func,  my_equal_to<char*> > my_unordered_map;


int main(){
    my_unordered_map location_map;

    char a[10] = "ab";
    location_map.insert(my_unordered_map::value_type(a, 10));
    char b[10] = "abc";
    location_map.insert(my_unordered_map::value_type(b, 20));

    char c[10] = "abc";
    location_map.insert(my_unordered_map::value_type(c, 20));

    printf("map size: %d\n", location_map.size());
    my_unordered_map::iterator it;
    if ((it = location_map.find("abc")) != location_map.end())
    {
        printf("found!\n");
    }

    return 0;
}

Remarque: l'Utilisation de char* le type de clé pour une unordered_map ou d'autres conteneurs STL peut être dangereux, un moyen sûr (semble être la seule) est la suivante: dans la fonction principale, new ou malloc un bloc (par exemple, un tableau de chaînes c) sur le tas et de le remplir avec c des chaînes de caractères. Insérez ces chaînes c dans unordered_map. Le bloc alloué de la mémoire est libérée à la fin de la fonction main (par delete ou free).

Vous n'avez pas besoin d'hériter de binary_function. Il pourrait même être abandonnés; je ne peux pas le chercher tout à l'heure.
Ce n'est pas le problème, mais les noms qui contiennent deux fois de suite les traits de soulignement (__x, __y) et les noms qui commencent par un caractère de soulignement suivi par une lettre majuscule (_Tp) sont réservés à la mise en œuvre (le compilateur et de sa bibliothèque). Ne les utilisez pas.
Entendez-vous les clés de la chaîne de relever char* pourrait-il être changé? Parce que Ce que je pense, c'est que vous voulez la clé de la constante chaîne de caractères pointée par const char *. Faire de chaque occurrence de char * à const char * à l'appui de cette
Il y a des questions plus profondes, pls prendre un regard sur les réponses et les commentaires ci-dessous.

OriginalL'auteur Bloodmoon | 2013-12-18