将int(C :: *)(int,char)类型转换为int(int,char)类型

时间:2013-04-25 16:39:32

标签: c++ templates c++11 bind member-function-pointers

我有一个班级:

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::mplboost::function_types的帮助下实施它,但我无法做到。

有经验的人能告诉我该怎么做吗?

PS。 VS 2010

1 个答案:

答案 0 :(得分: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);

这是live example

修改

如果您仅限于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...