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

C++ how to pass method as a template argument

本文关键字:参数传递 方法 C++      更新时间:2023-10-16

假设我有一个类X

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

创建一个我想传入的std::tr1::unordered_map<X, int, HashFn> X::hash()HashFn .我知道我可以声明自己的函子对象。我觉得应该有一种方法可以通过直接传递指向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;

不,没有。 原因是用作 HashFn 的任何内容都必须采用单个参数,该参数是对容器中对象的常量引用。 X::hash接受单个参数,该参数是指向容器中对象的 const 指针(在这种情况下,this指针是隐式的第一个参数(,因此无法自行使用该函数。

你可能会使用一些绑定魔法,使用boost::lambda和boost::bind。 我不确定如何,但它可能看起来像这样:

boost::bind(&X::hash, &_1);

这将创建一个函数对象,该对象将使用指针调用 X::hash。

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 来查找类型;否则,您最好编写自己的函数对象,如您所提到的。