6

おそらく恥ずかしいほど単純な問題があります。クラスでメンバー関数を渡し、呼び出します。BOOST バインド (およびまたは関数) を使用したいのはわかっていますが、その概念はまだよく理解していません。

次のコードは、問題を抱えてコンパイルおよび実行されます。しかし、「f3」関数を非静的クラス関数に変更したい場合は、楽しみが始まります。

#include <iostream>
#include <inttypes.h> 
#include <boost/bind.hpp>
#include <boost/function.hpp>

class Test
{
public:
  void f1();
private:
  void f2(void (*callfunc)(uint32_t));
  static void f3(uint32_t x);
};

void Test::f1(){
  f2(f3);
}

void Test::f2(void (*callfunc)(uint32_t)){
  (*callfunc)(42);
}

void Test::f3(uint32_t x){
  std::cout << "x: " << x << std::endl;
}

int main(int argc, char ** argv)
{
  Test ct;
  ct.f1();
  return 0;
}

さて、変更後

static void f3(uint32_t x);

void f3(uint32_t x);

コンパイラは満足せず、「エラー: 'Test::f2()' の呼び出しに一致する関数がありません」と通知します。

boost::bind および boost::function に関する多くの SO 投稿を読んだ後、f2() の定義と、f1() が f2() を呼び出して、f3() を呼び出すターゲットとして指定する方法を変更する必要があると思いますが、それとは別に...私が試したboost::bindとboost関数のすべての組み合わせは、惨めにコンパイルに失敗しました。

これをどのように書く必要がありますか?おまけの質問として、boost::bind と boost::function に関する簡単な入門書はありますか? BOOST のドキュメントはあまり役に立ちませんでした。

B.

4

2 に答える 2

8

boost::function は、関数シグネチャを取るテンプレート クラスです。function0、function1 なども使用できます。

boost::function< void(uint32_t) >

関数のように見える「callable」を定義します。つまり、タイプの単一のパラメーターを取り、uint32_tvoid を返します。

適切な番号付きテンプレートはfunction1< void, uint32_t >. これらは常に最初に戻り値の型を示し、次にパラメーターを順番に示します。

boost::bindは、渡された引数を推測し、ファンクターを作成する非常に特別な関数です。

void(uint32_t) を作成するのではなく、1 つのパターンを持つものを作成します。

したがって、署名を次のように変更します。

void f2(boost::function<void(uint32_t)>);

次に、次のように呼び出すことができます。

f2( boost::bind( &Test::f3, this, _1 ) );

奇妙な _1 は、boost::bind にパラメーターを配置する必要がある場所を伝える「プレースホルダー」であることに注意してください。uint32_t

于 2011-03-09T11:55:37.973 に答える
5

First, I 'll explain the reason that removing the static gives you a compilation error:

Take a look at this signature:

void (*callfunc)(uint32_t)

This is a pointer to free function that takes an uint32_t and returns void. When f3 is declared inside Test as

void f3(uint32_t x);

then f3 is a member function of class Test that takes an uint32_t and returns void. Therefore, there is no f3 that matches the type of the argument that f2 is expecting.

As for how boost::function and boost::bind can be used to provide a solution:

void Test::f1(){
    boost::function<void (uint32_t)> f = boost::bind(&Test::f3, this, _1);
    f2(f);
}

Update:

Finally, regarding a tutorial: I found this useful when learning about functors (which is what boost::function is and boost::bind returns) in the past. It doesn't mention boost specifically, but once you understand what exactly is going on in a lower level you will find using boost a breeze.

于 2011-03-09T11:28:21.503 に答える