假设我有一堂课X
:
class X {
// ...
size_t hash() const { return ...; }
};
我想创建一个std::tr1::unordered_map<X, int, HashFn>
我想
X::hash()
作为HashFn
. 我知道我可以声明我自己的仿函数对象。我觉得应该有一种方法可以通过直接将指针传递给X::hash()
.
有没有?
假设我有一堂课X
:
class X {
// ...
size_t hash() const { return ...; }
};
我想创建一个std::tr1::unordered_map<X, int, HashFn>
我想
X::hash()
作为HashFn
. 我知道我可以声明我自己的仿函数对象。我觉得应该有一种方法可以通过直接将指针传递给X::hash()
.
有没有?
不,没有。原因是用作 HashFn 的任何内容都必须采用单个参数,该参数是对容器中对象的 const 引用。 X::hash
接受单个参数,它是指向容器中对象的 const指针this
(在这种情况下,指针是隐式的第一个参数),因此无法自行使用该函数。
你可能使用了一些绑定魔法,使用 boost::lambda 和 boost::bind。我不完全确定如何,但它可能看起来像这样:
boost::bind(&X::hash, &_1);
它创建了一个函数对象,它将使用指针调用 X::hash。
不; 正如您所展示的,您需要一个小型实用程序结构:
#include <functional>
template<typename T, std::size_t (T::*HashFunc)() const = &T::hash>
struct hasher : std::unary_function<T, std::size_t>
{
std::size_t operator ()(T const& t) const
{
return (t.*HashFunc)();
}
};
然后你可以创建一个unordered_map
这样的:
std::tr1::unordered_map<X, int, hasher<X> > m;
size_t hash() const { return ...;}
计算哈希值的函数采用Key
您的函数不采用的类型参数。因此,它的签名一开始就是错误的。
既然你想实现一个函数,而不是一个仿函数,那么应该这样做:
size_t hash(const KeyType &key)
{
return /*calculate hash and return it*/;
}
使其成为static
成员函数并将其作为成员函数传递X::hash
或使其成为自由函数,是您的选择。
你不能直接,但你可以包装它。最简单的方法是使用boost::mem_fn()
,或者如果您的编译器支持它们,则使用标准等效项:(tr1::mem_fn()
来自 TR1)或std::mem_fn()
(来自 C++11)。
编辑:其实它不是那么简单。mem_fn()
对于函数参数可以正常工作,但由于未指定其返回类型,因此很难用作模板参数。如果您有 C++11 支持,您可以使用它decltype
来查找类型;否则你可能最好写你自己的函数对象,就像你提到的那样。