C ++如何将方法作为模板参数传递

时间:2011-04-11 14:32:38

标签: c++ templates hash unordered-map

假设我有一个班级X

class X {
    // ...
    size_t hash() const { return ...; }
};

我想创建一个{I}我要传递的地方 std::tr1::unordered_map<X, int, HashFn>X::hash()。我知道我可以声明自己的仿函数对象。我觉得 应该有一种方法可以通过直接将指针传递给HashFn来实现。

有吗?

4 个答案:

答案 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来查找类型;否则你最好自己编写自己的函数对象。