我有一个班级:
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::mpl
或boost::function_types
的帮助下实施它,但我无法做到。
有经验的人能告诉我该怎么做吗?
PS。 VS 2010
答案 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...