boost :: bind возвращает объект функции, который является аргументом функции, для которой требуется указатель

Я делаю C ++ кодирование на Linux о boost :: bind.

Возвращаемый тип данных 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 называется» не печатается, почему?

#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 функциональный объект в указатель на функцию?

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( &pound_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 на функцию-указатель.

Я думаю, что читать это будет интересно.

понизить boost :: function для простого указателя на функцию

В вашем случае — вы не можете использовать targetИтак, посмотрите на ответ Яна

2

Единственное, что вы можете передать как указатель на функцию — это функция. Нет функциональных объектов, нет лямбд, нет ничего. Просто глобальные функции.

0
По вопросам рекламы [email protected]