c++c++11boostfunction-binding

boost::bind()-like thing, but for function calls


Given boost::bind or the std:: equivalents, I can make this:

int f(int a, int b)
{
    return a + b;
}

auto f_two = boost::bind(f, 1, 1);

So that f_two() will return 2 by effectively calling an intermediate function that calls f(1, 1) via whatever implementation mechanism, perhaps something along the lines of:

double f_two_caller()
{
     return f(stored_arg_1, stored_arg_2);
}

However, my use case is that I would want to bind a prefix function so instead I could say:

auto f_print = boost::bind(printf, "Hello, world!\n");
auto f_print_and_two = boost::bind_with_prefix(f, f_print, 1, 1);

So f_print_and_two() effectively executes:

double f_print_and_two_caller()
{
    f_print(f_print.stored_arg_1);
    return f(stored_arg_1, stored_arg_2);
}

I'm sure there's a proper name for this technique that I could use to look up the solution, but I can't think of it right now...


Solution

  • template<class First, class Second>
    struct compose_t {
        First first;
        Second second;
        template<class...Args>
        auto operator()(Args&&...args)
        -> decltype( std::declval<Second&>()( std::declval<First&>()( std::declval<Args>()... ) ) )
        { return second(first( std::forward<Args>(args)... ) ); }
    };
    template<class First, class Second>
    compose_t<typename std::decay<First>::type, typename std::decay<Second>::type>
    compose( First&& first, Second&& second ){ return {std::forward<First>(first), std::forward<Second>(second)}; }
    

    this is functional composition.

    auto f_print = std::bind(printf, "Hello, world!\n");
    
    auto f_print_and_two = std::bind( compose(f, f_print), 1, 1 );
    
    int main() {
        f_print_and_two();
    }
    

    and done.

    Note that function composition can be chained. You can even write a variardic compose function based on the above.