【问题标题】:typedef function declaration with class - non-static member call?带有类的typedef函数声明-非静态成员调用?
【发布时间】: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 的范围内,这使得无需访问散列映射对象就可以编写散列函数。但是,如果您坚持使用您的模型,请在每次调用时将存储桶大小作为参数传递给哈希函数。

标签: c++ c++11 typedef


【解决方案1】:

hashCompressFunction 是成员函数,与普通函数有很大不同。成员函数有一个隐含的this 指针,并且总是需要在对象上调用。 为了将其分配给std::function,您可以使用std::bind 绑定当前实例:

hashCompress = std::bind(&HashMap::hashCompressFunction, 
                         this, std::placeholders::_1);

不过,您应该看看标准库是如何做到的,std::hash

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2014-04-14
    相关资源
    最近更新 更多