Search code examples
c++boostboost-bindboost-function

Passing function pointer arguments with boost


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);
}

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.