Passing function pointer arguments with boost

boost, boost-bind, boost-function, c++

Solution

You can use `boost::function<>` to make it possible using different types of callable objects as the function's input.

What follows is an example using C++11 (see the remarks after this example). This is how you would rewrite your function:

#include <functional>
#include <string>
#include <iostream>

void PassFxn(std::function<int(float, std::string, std::string)> func)
//           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
   int result = func(12, "a", "b"); // call using function object
   std::cout << result << std::endl;
}

These are a couple of functions to test it with:

int DoIt(float f, std::string s1, std::string s2)
{
    std::cout << f << ", " << s1 << ", " << s2 << std::endl;
    return 0;
}

int DoItWithFourArgs(float f, std::string s1, std::string s2, bool b)
{
    std::cout << f << ", " << s1 << ", " << s2 << ", " << b << std::endl;
    return 0;
}

struct X
{
    int MemberDoIt(float f, std::string s1, std::string s2)
    {
        std::cout << "Member: " << f << ", " << s1 << ", " << s2 << std::endl;
        return 0;
    }

    static int StaticMemberDoIt(float f, std::string s1, std::string s2)
    {
        std::cout << "Static: " << f << ", " << s1 << ", " << s2 << std::endl;
        return 0;
    }
};

And here is the test routine:

int main()
{
    PassFxn(DoIt); // Pass a function pointer...

    // But we're not limited to function pointers with std::function<>...

    auto lambda = [] (float, std::string, std::string) -> int
    {
        std::cout << "Hiho!" << std::endl;
        return 42;
    };

    PassFxn(lambda); // Pass a lambda...

    using namespace std::placeholders;
    PassFxn(std::bind(DoItWithFourArgs, _1, _2, _3, true)); // Pass bound fxn

    X x;
    PassFxn(std::bind(&X::MemberDoIt, x, _1, _2, _3)); // Use a member function!

    // Or, if you have a *static* member function...
    PassFxn(&X::StaticMemberDoIt);

    // ...and you can basically pass any callable object!
}

And here is a live example.

REMARKS:

You can easily change `std::function<>` into `boost::function<>` and `std::bind<>` into `boost::bind<>` if you are working with C++03 (in fact, Boost.Function is what inspired `std::function<>` and later became part of the Standard C++ Library). In this case, instead of including the `<functional>` header, you will have to include the `boost/function.hpp` and `boost/bind.hpp` headers (the latter only if you want to use `boost::bind`).

For a further example that should give you a feeling of the power that `std::function<>` / `boost::function<>` gives you through its ability of encapsulating any kind of callable object, also see this Q&A on StackOverflow.

Problem

Can the following function pointer passing be simplified/improved with the use of boost::function and/or boost::bind? ``` void PassPtr(int (*pt2Func)(float, std::string, std::string)) { int result = (*pt2Func)(12, "a", "b"); // call using function pointer cout << result << endl; } // execute example code void Pass_A_Function_Pointer() { PassPtr(&DoIt); } ```

Original source

Related problems