C++ bind function for use as argument of other fun

2019-04-07 04:51发布

问题:

I have a function that requires a function pointer as argument:

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

Now I want to use a certain function that has three arguments in this function:

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

How can I bind the first argument of c so that I'm able to do:

int i = func(10, c_bound);

I've been looking at std::bind1st but I cannot seem to figure it out. It doesn't return a function pointer right? I have full freedom to adapt func so any changes of approach are possible. Althoug I would like for the user of my code to be able to define their own c...

note that the above is a ferocious simplification of the actual functions I'm using.

The project sadly requires C++98.

回答1:

You can't do that. You would have to modify func to take a function-object first. Something like:

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

In fact, there is no need for b to be an std::function, it could be templated instead:

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

but I would stick with the std::function version for clarity and somewhat less convoluted compiler output on errors.

Then you would be able to do something like:

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

Note all this is C++11, but you can do it in C++03 using Boost.



回答2:

Well, if you know at compile time, what you have to bind c with, you could define a new function

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

That's obviously not a generic solution but might solve your current problem. Otherwise K-ballo's solution seems to be the only easy generic one. However, that requires you to be able to change the signature of func. If you really have an API that you can't touch the signature, and you still need to bind an argument AND if the above solution doesn't solve your specific case: (Caution, overkill ahead) I've always wanted to use an LLVM based solution to compile a function at runtime and pass its address in such situations.



回答3:

You would be unable to use a 3 argument function as a 2 argument function; Mainly because there is no real way to determine what the 3rd parameter would do.

While the above answer would work, here is another option:

If one of the parameters for c(), in use within func, is constant, you could write a wrapper function for c(int, int, int):

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

or, if you can determine the 3rd parameter from the two given parameters, you can also try:

int e(int a, int b)
{
    int extra = 0;
    ///Determine extra from a, and b
    return c(a, b, c);
}


标签: c++ bind