boost::bind 返回一个函数对象,它是需要指针的函数的参数
Posted
技术标签:
【中文标题】boost::bind 返回一个函数对象,它是需要指针的函数的参数【英文标题】:boost::bind return a function object which is the argument for a function that requires pointer 【发布时间】:2012-09-14 22:02:44 【问题描述】:我正在 Linux 上进行关于 boost::bind 的 C++ 编码。
boost::bind 的返回数据类型是一个函数对象,它是另一个函数bridge_set_pound_var_func 的输入参数。
但是,bridge_set_pound_var_func 的输入参数必须是函数指针。 bridge_set_pound_var_func 的接口不能改变。
代码如下:
#include <boost/bind.hpp>
#include <iostream>
using namespace boost;
class myA
public:
int bridge_set_pound_var_func( int (*pound_var_func)(const char *, char *, void *), void *arg ) std::cout << "bridge_set_pound_func is called " << std::endl ; return 0;
;
class myC
public:
myA *myOA;
int func(const char * poundVar , char * t1, void * t2);
int myCCall() myOA->bridge_set_pound_func( (boost::bind(&myC::func, this)), (void *)this ); return 0;
;
int myC::func(const char * poundVar , char * t1, void * t2)
std::cout << "myC::func is called " << std::endl;
return 1;
int main()
myC myCO ;
myC *m1p = &myCO ;
m1p->myCCall() ;
return 0 ;
// EOF
我得到编译错误:
error: no matching function for call to
'myA::bridge_set_pound_func(boost::_bi::bind_t<int (&)(const char*, char*, void*), boost::_mfi::dm<int ()(const char*, char*, void*), myC>, boost::_bi::list1<boost::_bi::value<myC*> > >, void*)'
note: candidates are: int myA::bridge_set_pound_func(int (*)(const char*, char*, void*), void*)
任何帮助将不胜感激。
而且,bridge_set_pound_var_func 的接口不能更改,因为它需要被许多其他函数调用。
这是有效的新代码。但是,“myC::func is called”没有打印出来,为什么?
#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>
using namespace boost;
class myA
public:
int bridge_set_pound_var_func( const boost::function3<int, const char *, char *, void *> f, void *arg ) std::cout << "bridge_set_pound_var_func is called " << std::endl ; return 0;
;
typedef int (*funcPtr)(const char *, char *, void *) ;
typedef boost::function0<int&> boostBindFuncType;
class myC
public:
myA *myOA;
int func(const char * poundVar , char * t1, void * t2);
int myCCall()
std::cout << "myCCall is called " << std::endl;
myOA->bridge_set_pound_var_func( (boost::bind(&myC::func, this, _1, _2, _3)), (void *)this );
return 0;
;
int myC::func(const char * poundVar , char * t1, void * t2)
std::cout << "myC::func is called " << std::endl;
return 1;
int main()
myC myCO ;
myC *m1p = &myCO ;
m1p->myCCall() ;
return 0 ;
我无法更改被许多其他函数调用的 bridge_set_pound_var_func 的接口。是否可以将 boost::bind 返回的函数对象转换为函数指针?
【问题讨论】:
旁注:为什么不使用 C++11functional
库?
这是一个非常大的项目的一小部分。如何使用 C++11 函数库?谢谢
使用更好的名称将使您的示例代码更易于理解。 myA
和 myC
不要告诉我任何事情,并且您不要在示例代码中的任何地方使用 f1
。 f1
似乎是 myA::bridge_set_pound_func()
——对吗?所以myA
对象实际上不是你的,那是固定的接口吗?
只需创建一个辅助函数并将一个指针传递给辅助函数。你可以编写帮助函数来做任何你想做的事情,包括调用boost::function
。
How can I cast or convert boost bind to C function pointer?的可能重复
【参考方案1】:
传统上,传递给回调的最终void *
参数是用户定义的数据。如果是这种情况,您可以创建一个帮助函数,让您传递函子。唯一的麻烦是您需要确保用户数据存在,直到不再调用回调 - 这在很大程度上取决于您的程序结构。我只是要泄漏对象,因为这是确保它继续存在的最简单方法。 (尽管您也会遇到包含 myC
对象的问题)。
class myC
public:
myA *myOA;
//NOTE: I've removed the void* ptr here, which should be user data.
// If you still need it you'll need to bind it away at functor creation time.
int func(const char * poundVar , char * t1);
int myCCall()
//TODO: Fix this intentional leak.
boost::function<int(const char*, char*)> * fn = new boost::function<int(const char*,char*)>( boost::bind(&myC::func,this) );
//Call our helper function instead of `set_pound_func`.
set_pound_func_with_functor(myOA, fn );
return;
;
// Function that is really passed to `set_pound_func` when
// set_pound_func_with_functor is called.
// It converts the user data back to a boost function and calls it.
int pound_func_with_functor(const char* d1, char* d2, void* user_data)
boost::function<int(const char*,char*)> * fn = static_cast< boost::function<int(const char*, char*) >( user_data );
return (*fn)(d1,d2);
//Helper function to make set_pound_func work with boost functions instead.
//NOTE: You are required to ensure the fn argument exists for long enough...
void set_pound_func_with_functor( myA * myOA, boost::function<int(const char *, char *)> & fn )
myOA->bridge_set_pound_var_func( £_func_with_functor, &fn );
【讨论】:
【参考方案2】:没有办法将boost::bind
结果转换为函数指针。
使用boost::function
int bridge_set_pound_var_func
( const boost::function<int(const char *, char *, void *)>& f, void *arg )
调用为
myOA->bridge_set_pound_var_func( (boost::bind(&myC::func, this, _1, _2, _3)),
(void *)this );
或使用template parameter
template<typename Func>
int bridge_set_pound_var_func( const Func& f, void *arg )
按第一种情况调用。
您不能将boost::bind
或boost::function
的结果转换为函数指针。
我认为阅读这篇文章会很有趣。
demote boost::function to a plain function pointer
在你的情况下 - 你不能使用target
,所以,看看伊恩的回答
【讨论】:
谢谢,但错误:testBoostBind.cpp:11: 错误:在 ', boost::_bi::list4<:_bi::value>, boost::arg , boost::arg, boost::arg >>, void*)' testBoostBind.cpp:11: 注意:候选是:int myA::bridge_set_pound_var_func() 语法函数boost::function2
而不是boost::function
(参见the docs)。无论如何,GCC 4.3.2 已经足够新,可以使用答案中显示的语法,所以你一定有一些我们没有看到的其他问题。您使用的是哪个版本的 Boost?
@runnerfrank :您使用的是 ancient 版本的 Boost -- 1.33.1 来自 2005 年 12 月。帮自己一个忙,更新最近 7 年内发布的内容年。 ;-]【参考方案3】:
唯一可以作为函数指针传递的就是函数。没有函数对象,没有 lambda,什么都没有。只是全局函数。
【讨论】:
"no lambdas" Captureless lambdas 很好。 “只是全局函数。”静态成员函数很好。 严格来说,两者是直接等价的。以上是关于boost::bind 返回一个函数对象,它是需要指针的函数的参数的主要内容,如果未能解决你的问题,请参考以下文章
使用 boost::bind 将成员函数绑定到 boost::bisect?