7

引数として関数ポインタを必要とする関数があります。

int func(int a, int (*b)(int, int))
{
    return b(a,1);
}

ここで、この関数で3つの引数を持つ特定の関数を使用したいと思います。

int c(int, int, int)
{
    // ...
}

の最初の引数をバインドして、次のことができるようにするにはどうすればよいcですか。

int i = func(10, c_bound);

私はずっと見てきましたstd::bind1stが、それを理解できないようです。関数ポインタを返しませんよね?私には適応する完全な自由がfuncあるので、アプローチの変更が可能です。Althoug私のコードのユーザーが自分のコードを定義できるようにしたいと思いますc...

上記は、私が使用している実際の関数を非常に単純化したものであることに注意してください。

プロジェクトは悲しいことにを必要としC++98ます。

4

3 に答える 3

12

あなたはそれをすることはできません。func最初に関数オブジェクトを取得するように変更する必要があります。何かのようなもの:

int func( int a, std::function< int(int, int) > b )
{
    return b( a, rand() );
}

実際、である必要はありません。代わりにテンプレート化bするstd::functionことができます。

template< typename T >
int func( int a, T b )
{
    return b( a, rand() );
}

しかし、私はstd::function明確にするためにバージョンを使い続け、エラーに関するコンパイラの出力はやや複雑ではありません。

そうすれば、次のようなことができるようになります。

int i = func( 10, std::bind( &c, _1, _2, some-value ) );

これはすべてC++11ですが、 Boostを使用してC++03で実行できることに注意してください。

于 2012-05-21T20:30:15.633 に答える
1

さて、コンパイル時にcをバインドする必要があるものがわかっている場合は、新しい関数を定義できます。

int c_bound(int a, int b) {
   return c(a,b,some_value);
}

これは明らかに一般的な解決策ではありませんが、現在の問題を解決する可能性があります。そうでなければ、K-balloのソリューションが唯一の簡単な一般的なソリューションのようです。ただし、そのためには、の署名を変更できる必要がありますfunc。署名に触れることができないAPIが本当にあり、それでも引数をバインドする必要がある場合、および上記の解決策で特定のケースが解決しない場合:(注意、先にやり過ぎ)私は常に実行時に関数をコンパイルし、そのような状況でそのアドレスを渡すためのLLVMベースのソリューション。

于 2012-05-21T20:37:25.060 に答える
0

3引数関数を2引数関数として使用することはできません。主な理由は、3番目のパラメーターが何をするかを決定する実際の方法がないためです。

上記の答えは機能しますが、別のオプションがあります。

c()内で使用されているのパラメータの1つfuncが定数の場合、次のラッパー関数を記述できますc(int, int, int)

int d(int a, int b)
{
   return c(a, b, 0); //use a constant parameter
}

または、指定された2つのパラメーターから3番目のパラメーターを判別できる場合は、次のことも試してください。

int e(int a, int b)
{
    int extra = 0;
    ///Determine extra from a, and b
    return c(a, b, c);
}
于 2012-05-21T20:40:08.370 に答える