c++boost-bind

How does boost::bind pass arguments in C++?


I'm having trouble understanding some parts of these lines of code:

fn_ = boost::bind(&CheckFeasibility, this, &world_, _1, _2, _3 );

if (robot_state_->setFromIK(arg1, arg2, arg3, arg4, arg5, fn_ ))

What is the purpose of this in the first line and when and how are the arguments of CheckFeasibility determined and passed to it?

Here is what the CheckFeasibility function looks like (I have omitted the data types of the arguments):

bool CheckFeasibility(*world, *state, *grp, *values)

Thank you


Solution

  • boost::bind, or nowadays std::bind, is used to bind some arguments to a function. The result is a function that takes less arguments (and returns the same thing).

    The line of code in your example is basically equivalent to:

    const auto fn_ = [this, &world](auto&& arg1, auto&& arg2, auto&& arg3) {
      return checkFeasibility(&world, arg1, arg2, arg3);
    };
    

    The arguments to bind are the function that you want to call, followed by all the arguments to the function. You can set them to fixed values or use the placeholders _1, _2 etc. to leave them out for now and pass them when you call the resulting function. The resulting function thus expects exactly as many arguments as the number of placeholders you use. You could also specify them in a different order to reorder arguments.

    For member functions, their implicit first argument is the this pointer, so here the second argument to bind is the object on which the function is called.

    In your example, the callback function passed to setFromIK is expected to take three parameters, but the authors only have a more general function that takes five (this and world are the extra ones.) So they make a more specific function out of this general function for which two parameters are already fixed. This is called Currying.

    Note that the C++ Core Guidelines recommend to use lambdas over bind, if possible. It is often more readable and possibly even faster because it's easier for the compiler to optimize, e.g. by inlining the called function. But this depends on the exact code and compiler.