假设我有这个:
void func(WCHAR* pythonStatement) {
// Do something with pythonStatement
}
我需要将它转换为void function(void),如下所示:
bind(func, TEXT("console.write('test')"))
现在我有这样的结构:
typedef void (__cdecl * PFUNCPLUGINCMD)();
struct FuncItem {
PFUNCPLUGINCMD pFunc;
// ...
};
如何将我的结构的pFunc设置为bind(func, "something")
?绑定返回lambda_functor而不是函数指针,那么如何将这个函子转换为函数指针?
感谢。
使用the wrapping "solution"(GitHub)
结束答案 0 :(得分:6)
我认为你不能,除非你把结果lamba_functor变成一个全局变量。
在这种情况下,您可以声明一个调用它的函数:
void uglyWorkaround() {
globalLambdaFunctor();
}
并将pFunc
设置为uglyWorkaround()
。
修改强>
只是旁注:如果您将静态文本绑定到函数调用,则可以完全省略bind()
调用并写入:
void wrapper() {
func(TEXT("console.write('test')"));
}
并将pFunc
设置为wrapper()
。
答案 1 :(得分:4)
绑定返回lambda_functor而不是函数指针,那么如何将这个仿函数转换为函数指针?
我认为你不能。然而,在我的头脑中,我可以想到几个选择:
使用boost::function<void()>
(或std::function()
,如果您的编译器支持TR1或C ++ 11)而不是void (*)()
。
它能够通过稍微兼容的签名绑定到任何东西。
将整个代码放入模板中,使PFUNCPLUGINCMD
成为模板参数,让函数模板参数推导出确切的类型。
实际上,这是前者的变体,您可以直接使用bind()
的结果,而不是让boost::function
抽象出血腥的细节。
创建一个调用boost::bind()
返回的仿函数的包装器
函数模板可能有助于让编译器找出确切的类型并生成合适的函数,尽管我没有尝试过这样做。但是,由于您不能使用bind()
的结果作为模板参数,但是需要让函数访问它,您需要一个全局变量。 (避免这种情况的能力是功能对象的主要优点之一,其中通用的std::function
非常通用。)
扩展您的PFUNCPLUGINCMD
回调类型以支持用户提供的参数。对于C回调,这通常是void*
。但是,如果将bind()
返回的对象的地址传递给回调,则需要将其转换为指向正确类型的指针 - AFAIK取决于提供给bind()
的参数。为了避免这种情况,你需要传递抽象出确切类型的东西。再次,std::function
来救援。
第一个想法是最好的,但它要求您能够更改PFUNCPLUGINCMD
。当PFUNCPLUGINCMD
需要与C兼容时,最后一个可能是最好的,因为它使用常见的C回调习惯用法。
答案 2 :(得分:0)
除非您想编写自己的即时编译器,否则不能这样做。或者,如果您控制接收代码,那么您可以使用boost::function<>
,其中将接受各种函数类型,包括指针和等函数对象由boost::bind
制作。