std :: hash特殊化仍然未被std :: unordered_map使用

时间:2015-05-07 12:46:31

标签: c++ templates c++11 std unordered-map

我正在尝试通过为std::hash<T>提供专门化来扩展const char,以便我可以在const char*中将std::unordered_map用作关键字类型。

这就是我的尝试:

#include <unordered_map>
#include <functional>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

namespace std
{
    template<>
    struct hash<const char*>
    {
        size_t operator()(const char* const& s) const
        {
           size_t h = 0;
           const char* tmp = s;

           while (*tmp)
              h = (h << 5) + h + (unsigned char)toupper(*tmp++);

           printf("hash of '%s' is (%ld)\n", s, h);
           return h;
        }
    };
}

int main(int argc, char* argv[])
{
   const char* name1= "Mark Nelson";
   const char* name2= strdup(name1);

   std::unordered_map<const char*, int> map;

   printf("Insert (%s)\n", name1);
   map[name1]= 100;

   printf("Lookup (%s)\n", name1);
   printf("map[%s](name1) = %d\n", name1, map.find(name1) != map.end() ? map.find(name1)->second : -1);
   printf("Lookup (%s)\n", name2);
   printf("map[%s](name2) = %d\n", name2, map.find(name2) != map.end() ? map.find(name2)->second : -1);

   return 0;
}

输出结果是什么:

Insert (Mark Nelson)
hash of 'Mark Nelson' is (121066894705597050)
Lookup (Mark Nelson)
hash of 'Mark Nelson' is (121066894705597050)
hash of 'Mark Nelson' is (121066894705597050)
map[Mark Nelson](name1) = 100
Lookup (Mark Nelson)
hash of 'Mark Nelson' is (121066894705597050)
map[Mark Nelson](name2) = -1

所以对我而言,std::unordered_map正在使用我提供的哈希实现来插入和查找。但由于某种原因,它没有通过name2找到值,这似乎是仍然使用指针比较。

这里有什么问题?我使用的是GCC 4.8.2,文件是用g++ -std=c++11 main.cc

编译的

1 个答案:

答案 0 :(得分:5)

无序地图需要两件事(ref):

  1. 哈希函数
  2. 相等的比较函数
  3. 所以你有(1)似乎工作,但是地图必须检查const char *是否相等,哪些转换为指针比较。为此,您可以指定自定义比较器(ref):

    struct cmp_str
    {
       bool operator()(char const *a, char const *b)
       {
          return std::strcmp(a, b) == 0;
       }
    };
    
    std::unordered_map<const char*, int, std::hash<const char *>, cmp_str> BlahBlah;