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

发布于 2024-10-31 17:35:54 字数 325 浏览 8 评论 0原文

假设我有一个类 X

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

我想创建一个 std::tr1::unordered_map 我想传入的地方 X::hash()HashFn。我知道我可以声明我自己的函子对象。我觉得 应该有一种方法可以通过直接传递指向 X::hash() 的指针来做到这一点。

有没有?

Suppose I have a class X:

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

I would like to create a std::tr1::unordered_map<X, int, HashFn> where I want to pass in
X::hash() as HashFn. I know I can declare my own functor object. I feel that
there should be a way to do this by directly passing a pointer to X::hash().

Is there?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

踏雪无痕 2024-11-07 17:35:54

不;正如您所展示的,您需要一个小的实用程序结构:

#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;

No; as you've shown it, you need a small utility struct:

#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)();
    }
};

Then you can create an unordered_map like so:

std::tr1::unordered_map<X, int, hasher<X> > m;
溺深海 2024-11-07 17:35:54

不,没有。原因是无论用作 HashFn 的任何内容都必须采用单个参数,该参数是对容器中对象的 const 引用。 X::hash 采用单个参数,该参数是指向容器中对象的 const 指针this 指针是隐式的第一个参数这种情况),所以单独使用该函数是不可能的。

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

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

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

No, there isn't. The reason is that whatever is used as your HashFn must take a single argument which is a const reference to an object in the container. X::hash takes a single argument which is a const pointer to an object in the container (the this pointer is an implicit first argument in this case), so using that function by it self is not possible.

You probably use some bind magic, using boost::lambda and boost::bind. I'm not exactly sure how, but it would probably look something like this:

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

Which creates a function object which will call X::hash with a pointer.

浅黛梨妆こ 2024-11-07 17:35:54
size_t hash() const { return ...;}

计算哈希值的函数采用一个 Key 类型的参数,而您的函数不采用该参数。因此它的签名一开始就是错误的。

由于您想要实现一个函数,而不是一个函子,因此应该如何完成:

size_t hash(const KeyType &key) 
{
    return /*calculate hash and return it*/;
}

将其设为 static 成员函数并将其作为 X::hash 传递或 make它是一个免费功能,由您选择。

size_t hash() const { return ...;}

A function which calculates hash value takes one parameter of type Key which your function doesn't take. Hence its signature is wrong to begin with.

Since you want to implement a function, rather than a functor, here is how it should be done:

size_t hash(const KeyType &key) 
{
    return /*calculate hash and return it*/;
}

Make it static member function and pass it as X::hash or make it a free function, is your choice.

情深缘浅 2024-11-07 17:35:54

不能直接贴,但是可以包起来。最简单的方法是使用 boost::mem_fn() 或标准等效项(如果您的编译器支持):tr1::mem_fn()(来自 TR1)或 std::mem_fn() (来自 C++11)。

编辑:实际上事情没那么简单。 mem_fn() 对于函数参数来说可以正常工作,但由于其返回类型未指定,因此很难用作模板参数。如果您有 C++11 支持,您可以使用 decltype 来查找类型;否则,您可能最好像您提到的那样编写自己的函数对象。

You can't directly, but you can wrap it. The easy way to do so is to use boost::mem_fn(), or the standard equivalents if your compiler supports them: tr1::mem_fn() (from TR1) or std::mem_fn() (from C++11).

EDIT: Actually it's not so simple. mem_fn() will work fine for a function parameter, but since its return type is unspecified it's difficult to use as a template parameter. If you have C++11 support you could use decltype to find the type; otherwise you're probably best off writing your own function object as you mentioned.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文