从成员函数指针类型生成函子

发布于 2024-08-06 20:37:31 字数 1272 浏览 5 评论 0原文

我正在尝试简化(通过 make_fn())生成对 arity 的成员函数预处理参数(通过 wrap())的函子n.
生成函子基本上可以工作,但到目前为止只能通过显式指定成员函数的参数类型来实现。
现在我想从它处理的成员函数类型生成正确的函子:

struct X {};

template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
bool wrap(C* c, X x) 
{
    return (c->*F)(process<T1>(x));
}

template<class C, typename T1, bool (C::*F)(T1)> 
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(F f) // <- problem here, F is not a type
{
    return boost::bind(&wrap<C, T1, F>, _1, _2);
}

但是,有了这个, vc++ 和 g++ 不会将 F 视为 make_fn() 参数的类型。我一定错过了这里明显的一些东西,并且感觉有点盲目。

我们的想法是它应该像这样工作:

struct A 
{
    bool f1(bool) { return true; }
};

void test()
{
    A a;
    X x;
    make_fn(&A::f1)(&a, x);
}

关于如何使其工作有什么想法吗?

背景:
我有一个固定的接口,简化后看起来像这样:

bool invoke(C* c, const char* const functionName, int argCount, X* args);

X 是一个变体类型,我必须将其转换为某些后端类型(int、std::string、...)。
为了处理这些调用,我有一个函子映射,可以按名称查找并将这些调用映射到某个实例的成员函数。
包装的目的是避免手动转换,而是生成为我执行转换或抛出的函子。我使用基于宏的解决方案,但该解决方案需要明确指定类型和参数计数。
通过函数重载解析,我希望从成员函数签名隐式生成正确的转换函子。

I am trying to simplify (via make_fn()) the generation of functors that preprocess parameters (via wrap()) for member functions of arity n.
Generating the functors is basically working, but until now only by explicitly specifying the parameter types for the member function.
Now i'd like to generate the correct functor from the member function type it handles:

struct X {};

template<class C, typename T1, bool (C::*F)(T1)>
inline // there are more for T1..TN
bool wrap(C* c, X x) 
{
    return (c->*F)(process<T1>(x));
}

template<class C, typename T1, bool (C::*F)(T1)> 
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(F f) // <- problem here, F is not a type
{
    return boost::bind(&wrap<C, T1, F>, _1, _2);
}

With this however, vc++ and g++ don't see F as a type for the parameter of make_fn(). I must miss something obvious here and am feeling somewhat blind.

The idea was that it should work like this:

struct A 
{
    bool f1(bool) { return true; }
};

void test()
{
    A a;
    X x;
    make_fn(&A::f1)(&a, x);
}

Any ideas on how to make that work?

Background:
I have a fixed interface which, when simplified, looks like this:

bool invoke(C* c, const char* const functionName, int argCount, X* args);

X is a variant type which i have to convert to certain backend types (int, std::string, ...).
To handle these calls i have a map of functors that are looked up by name and map these calls to member functions of some instance.
The intention of the wrapping is to avoid manual conversions and instead generate functors which do the conversion for me or throw. I have this working with a macro based solution, but that solution requires to specify the types and the parameter count explicitly.
Via function overload resolution i hope to generate the correct converting functor implicitly from the member function signature.

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

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

发布评论

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

评论(1

我是有多爱你 2024-08-13 20:37:31

在我看来,您正在尝试将传递给函数的指针转换为非类型模板参数,这恐怕行不通(请参阅对您问题的评论)。

您可以做的是将函数指针存储在函数对象中。以下内容似乎可以编译:

#include <boost/bind.hpp>
#include <boost/function.hpp>

struct X {};

template <class T>
bool process(X) { return true; }


template <class C, class T1, class Func>
struct wrap1
{
    typedef bool result_type;
    Func f;

    wrap1(Func f): f(f) {}

    bool operator()(C* c, X x)
    {
        return (c->*f)(process<T1>(x));
    }
};

template<class C, typename T1>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(bool (C::*f)(T1))
{
    return boost::bind(wrap1<C, T1, bool (C::*)(T1)>(f), _1, _2);
}


struct A
{
    bool f1(bool) { return true; }
};

void test()
{
    A a;
    X x;
    make_fn(&A::f1)(&a, x);
}

但是,我不确定这是否有任何好处以及如何创建其余的包装器。对于后者,您可能只需要一个支持可变参数模板的编译器。 :)

It appears to me that you are attempting to turn a pointer passed to a function into a non-type template argument, which I'm afraid is not going to work (see comments to your question).

What you could do, is to store the function pointer in a function object. The following appears to compile:

#include <boost/bind.hpp>
#include <boost/function.hpp>

struct X {};

template <class T>
bool process(X) { return true; }


template <class C, class T1, class Func>
struct wrap1
{
    typedef bool result_type;
    Func f;

    wrap1(Func f): f(f) {}

    bool operator()(C* c, X x)
    {
        return (c->*f)(process<T1>(x));
    }
};

template<class C, typename T1>
inline // there are more for T1..TN
boost::function<bool (C*, X)> make_fn(bool (C::*f)(T1))
{
    return boost::bind(wrap1<C, T1, bool (C::*)(T1)>(f), _1, _2);
}


struct A
{
    bool f1(bool) { return true; }
};

void test()
{
    A a;
    X x;
    make_fn(&A::f1)(&a, x);
}

However, I'm not sure if that is any good and how you would create the rest of the wrappers. For the latter you might just get a compiler that supports variadic templates. :)

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