将 int(C::*)(int, char) 类型转换为 int(int, char) 类型
Posted
技术标签:
【中文标题】将 int(C::*)(int, char) 类型转换为 int(int, char) 类型【英文标题】:convert type int(C::*)(int, char) to type int(int, char) 【发布时间】:2013-04-25 16:39:32 【问题描述】:我有一堂课:
struct C
int F(int, char) return 0;
;
我需要创建一个std::function
,它将为变量c
调用C::F
函数:
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。对比 2010
【问题讨论】:
你不能简单地使用auto f = std::bind(&C::F, &c, _1, _2);
吗?
在实际应用中 f 是结构的成员,所以我不能在那里使用“auto”
【参考方案1】:
如果您需要一种类型特征 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...
【讨论】:
VS 2010 不支持可变参数模板 :( @Alek86:哦,对了,忘了。然后你必须定义几个这样的模板 @Alek86:好的,很高兴它有帮助:)以上是关于将 int(C::*)(int, char) 类型转换为 int(int, char) 类型的主要内容,如果未能解决你的问题,请参考以下文章