假设我有一个班级X
:
class X {
// ...
size_t hash() const { return ...; }
};
我想创建一个{I}我要传递的地方
std::tr1::unordered_map<X, int, HashFn>
为X::hash()
。我知道我可以声明自己的仿函数对象。我觉得
应该有一种方法可以通过直接将指针传递给HashFn
来实现。
有吗?
答案 0 :(得分:2)
不,没有。原因是无论用作HashFn的是什么,都必须使用一个参数,该参数是对容器中对象的const引用。 X::hash
将一个const 指针的参数作为容器中的对象(在这种情况下this
指针是隐式的第一个参数),因此使用该函数它本身是不可能的。
你可能使用一些绑定魔法,使用boost :: lambda和boost :: bind。我不确定如何,但它可能看起来像这样:
boost::bind(&X::hash, &_1);
它创建了一个函数对象,它将使用指针调用X :: hash。
答案 1 :(得分:2)
没有;如你所示,你需要一个小实用程序结构:
#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;
答案 2 :(得分:0)
size_t hash() const { return ...;}
计算哈希值的函数采用一个类型为Key
的参数,您的函数不会使用该参数。因此,它的签名开始时是错误的。
由于你想要实现一个函数,而不是一个函子,下面是它应该如何完成:
size_t hash(const KeyType &key)
{
return /*calculate hash and return it*/;
}
将其设为static
成员函数并将其作为X::hash
传递或将其设为自由函数,是您的选择。
答案 3 :(得分:0)
你不能直接,但你可以包装它。这样做的简单方法是使用boost::mem_fn()
或标准等效项,如果您的编译器支持它们:tr1::mem_fn()
(来自TR1)或std::mem_fn()
(来自C ++ 11)。
mem_fn()
对函数参数可以正常工作,但由于它的返回类型未指定,因此很难用作模板参数。如果您有C ++ 11支持,可以使用decltype
来查找类型;否则你最好自己编写自己的函数对象。