1

私はBoost::bindについてLinuxで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 iscalled」は出力されません。なぜですか?

#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が返された関数オブジェクトを関数ポインタに変換することは可能ですか?

4

3 に答える 3

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ので、イアンの答えを見てください

于 2012-09-14T22:28:21.710 に答える
2

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 );
}
于 2012-09-15T01:30:20.253 に答える
0

関数ポインタとして渡すことができるのは関数だけです。関数オブジェクトもラムダも何もありません。ただグローバル関数。

于 2012-09-14T22:07:41.970 に答える