【发布时间】:2013-11-15 03:06:42
【问题描述】:
我有一个名为 HashMap 的类,它的一个构造函数可以接受用户提供的HashFunction——然后是我实现的那个。
我面临的问题是在没有提供时定义我自己的HashFunction。以下是我正在使用并从 gcc 获取错误的示例代码:
HashMap.cpp:20:20: error: reference to non-static member function must be called
hashCompress = hashCompressFunction;
^~~~~~~~~~~~~~~~~~~~`
头文件:
class HashMap
{
public:
typedef std::function<unsigned int(const std::string&)> HashFunction;
HashMap();
HashMap(HashFunction hashFunction);
...
private:
unsigned int hashCompressFunction(const std::string& s);
HashFunction hashCompress;
}
源文件:
unsigned int HashMap::hashCompressFunction(const std::string& s)
{
... my ultra cool hash ...
return some_unsigned_int;
}
HashMap::HashMap()
{
...
hashCompress = hashCompressFunction;
...
}
HashMap::HashMap(HashFunction hf)
{
...
hashCompress = hf;
...
}
【问题讨论】:
-
hashCompressFunction是一个成员函数,它与独立函数有不同的签名。 -
大多数哈希实现采用仿函数是有原因的
-
@billz 好的,这是有道理的。通过在课堂外删除我的
HashCompressFunction,我可以编译。然而现在问题出现了,HashCompressFunction不能再访问HashClass内的成员函数或变量—— IE 存储桶大小。是制作静态类的唯一解决方案吗? -
@Adam:糟糕的设计。如果你的散列函数需要知道桶的大小,则不可能编写外部散列函数。 (这就是标准库的哈希接口返回 size_t 的原因:哈希映射本身负责减小 size_t 以适应存储桶大小。)您不需要从类中删除
hashCompressFunction;您只需要将其设为静态(当然,静态函数仍然无法访问实例状态)。 -
@Adam:不,它没有。散列函数的调用者可以做任何必要的事情来限制上限(例如模数),只要它知道范围是多少。 C++11(基于 boost 实现)要求散列函数均匀分布在
size_t的范围内,这使得无需访问散列映射对象就可以编写散列函数。但是,如果您坚持使用您的模型,请在每次调用时将存储桶大小作为参数传递给哈希函数。