2

我有一堂课:

struct C {
    int F(int, char) { return 0; }
};

我需要创建一个std::function,它将调用C::F一个变量的函数c

C c;
std::function<int(int, char)> f;
...
f = std::bind(&C::F, &c, _1, _2);

但是如果函数的签名被改变,我也需要改变 std::function 。

所以我不想重复签名:

C c;
std::function<delete_class<decltype(&C::F)>::type> f;
...
f = std::bind(&C::F, &c, _1, _2);

其中 delete_class 是一些魔术助手,它将类型更改int(C::*)(int, char)int(int, char).

我怀疑,我可以在boost::mplor的帮助下实现它boost::function_types,但我做不到。

有经验的人可以告诉我怎么做吗?

PS。对比 2010

4

1 回答 1

4

如果您需要一种delete_class可以按照您的意愿工作的类型特征,那么这个应该可以完成这项工作:

template<typename S>
struct delete_class;

template<typename R, typename C, typename... Ts>
struct delete_class<R (C::*)(Ts...)>
{
    using type = R(Ts...);
};

然后将满足以下断言:

static_assert(
    std::is_same<delete_class<decltype(&C::F)>::type, 
    int(int, char)
    >::value, "!");

然后您可以使用delete_class<>您建议的方式:

std::function<delete_class<decltype(&C::F)>::type> f;
C c;
f = std::bind(&C::F, &c, _1, _2);

这是一个活生生的例子

编辑:

如果您仅限于 VC10 支持(即没有可变参数模板),则必须定义delete_class主模板的几个部分特化:

template<typename S>
struct delete_class;

template<typename R, typename C>
struct delete_class<R (C::*)()>
{
    typedef R(type)();
};

template<typename R, typename T>
struct delete_class<R (C::*)(T)>
{
    typedef R(type)(T);
};

template<typename R, typename T, typename U>
struct delete_class<R (C::*)(T, U)>
{
    typedef R(type)(T, U);
};

template<typename R, typename T, typename U, typename V>
struct delete_class<R (C::*)(T, U, V)>
{
    typedef R(type)(T, U, V);
};

// And so on...
于 2013-04-25T16:44:48.047 回答