C++:哈希表 - 为什么这个代码无法编译?

5

我有以下的C++代码:

#include <iostream>
#include <google/dense_hash_map>
#include <string.h>

using google::dense_hash_map;      // namespace where class lives by default
using std::cout;
using std::endl;
using std::tr1::hash;  // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
  }
};

int main(void){
  dense_hash_map<const int, const char*, hash<const int>, eqstr> months;

  months.set_empty_key(0);
  months[1234] = "1234";

  cout << "1234:" << months[1234] << endl;
}

您可以看到,我正在使用Google的sparsehash库来实现哈希表。

我将整数用作键,将字符串用作值。

但是我一直得到以下编译错误,我无法解决:

生成所有构建文件:../src/Main.cpp调用:GCC C++编译器 g ++ -O0 -g3 -Wall -c -fmessage-length = 0 -MMD -MP -MF“src / Main.d”-MT“src / Main.d” -o“src / Main.o”“../ src / Main.cpp”从中包含的文件 /usr/local/include/google/dense_hash_map:104:0, 来自../src/Main.cpp: /usr/local/include/google/sparsehash/densehashtable.h:在成员函数‘bool google :: dense_hashtable :: KeyInfo :: equals(const key_type&,const key_type&)const [with Value = std :: pair,Key = int,HashFcn = std :: tr1 :: hash,ExtractKey = google :: dense_hash_map,eqstr> :: SelectKey,SetKey = google :: dense_hash_map,eqstr> :: SetKey,EqualKey = eqstr,Alloc = google :: libc_allocator_with_realloc

,key_type = int]’中: /usr/local/include/google/sparsehash/densehashtable.h:1306:32:<br/ > 实例化于‘bool google :: dense_hashtable :: equals(const key_type&,const key_type&)const [with Value = std :: pair,Key = int,HashFcn = std :: tr1 :: hash,ExtractKey = google :: dense_hash_map,eqstr> :: SelectKey,SetKey = google :: dense_hash_map,eqstr> :: SetKey,EqualKey = eqstr,Alloc = google :: libc_allocator_with_realloc,key_type = int]’ /usr/local/include/google/sparsehash/densehashtable.h:514:5:
实例化于‘void google :: dense_hashtable :: set_empty_key(google :: dense_hashtable :: const_reference)[with Value = std :: pair,Key = int,HashFcn = std :: tr1 :: hash,ExtractKey = google :: dense_hash_map,eqstr> :: SelectKey,SetKey = google :: dense_hash_map,eqstr> :: SetKey,EqualKey = eqstr,Alloc = google :: libc_allocator_with_realloc,google :: dense_hashtable :: const_reference = const std :: pair&]’/usr/local/include/google/dense_hash_map:298:5:
实例化于‘void google :: dense_hash_map :: set_empty_key(google :: dense_hash_map :: key_type&)[with Key = int,T = const char *,HashFcn = std :: tr1 :: hash,EqualKey = eqstr,Alloc = google :: libc_allocator_with_realloc,google :: dense_hash_map :: key_type = int]’../src/Main.cpp:21:25:从这里实例化 /usr/local/include/google/sparsehash/densehashtable.h:1293:39:错误: 从‘google :: dense_hashtable,int,std :: tr1 :: hash,google :: dense_hash_map,eqstr,google :: libc_allocator_with_realloc > > :: SelectKey,eqstr,google :: libc_allocator_with_realloc,google :: dense_hash_map,eqstr,google :: libc_allocator_with_realloc > > :: key_type’到‘const char *’的无效转换 /usr/local/include/google/sparsehash/densehashtable.h:1293:39:错误: 初始化‘bool eqstr :: operator()(const char *,const char *)const’的参数1 /usr/local/include/google/sparsehash/densehashtable.h:1293:39:错误: 从‘google :: dense_hashtable,int,std :: tr1 :: hash,google :: dense_hash_map,eqstr,google :: libc_allocator_with_realloc > > :: SelectKey,eqstr,google :: libc_allocator_with_realloc,google :: dense_hash_map,eqstr,google :: libc_allocator_with_realloc > > :: key_type’到‘const char *’的无效转换 /usr/local/include/google/sparsehash/densehashtable.h:1293:39:错误: 初始化‘bool eqstr :: operator()(const char *,const char *)const’的参数2 make: * [src / Main.o]错误1

看起来非常啰嗦,我无法理解。

需要补充的是,当我使用字符串作为键,整数作为值时,它可以正常工作:

dense_hash_map<const char*, int, hash<const char*>, eqstr> months;
...
months["february"] = 2;   //works fine

有人有什么想法吗?

非常感谢您的帮助。


编辑:现在已经搞定了!

#include <iostream>
#include <google/dense_hash_map>
#include <string.h>

using google::dense_hash_map;      // namespace where class lives by default
using std::cout;
using std::endl;
using std::tr1::hash;  // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS

struct eqstr
{
  bool operator()(int s1, int s2) const
  {
    return (s1 == s2); //|| (s1 && s2 && strcmp(s1, s2) == 0);
  }
};

int main(void){
  dense_hash_map<int, const char*, hash<int>, eqstr> months;

  months.set_empty_key(0);
  months[1234] = "1234";

  cout << "1234:" << months[1234] << endl;
}

完全忘记编辑eqstr结构以适应新的数据类型... 头撞桌子


1
投诉是eqstr应该期望键类型,而键类型不是const char*。根据您的声明,我不知道足够关于类型的信息来确定键类型是什么(无符号整数?)。 - antlersoft
1个回答

3
正如你自己指出的那样,如果使用const char*作为键,则可以正常工作。哈希映射确实需要一个哈希函数将键哈希到桶中,并需要一个比较函数来在桶内建立严格弱排序 - 所有这些都是针对键类型,值类型仅被存储!因此,为int定义一个比较函数可以使其工作(我不知道google::dense_hash_map是否支持const int,但我认为应该使用int)。

1
是的,我刚刚通过艰难的方式弄清楚了这一点...非常感谢您的回答! - Eamorr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接