C++: std::function and std::bind

std::function and std::bind were originally part of the Boost C++ Library, but they were incorporated into the C++11 standard.

std::function is a standard library template class that provides a very convenient wrapper for a simple function, a functor, a method, or a lambda expression.

For example, if programmers want to store several functions, methods, functors, or lambda expressions in a vector, they could write something like this:

#include <functional>
#include <iostream>
#include <string>
#include <vector>
 
void execute(const std::vector<std::function<void ()>>& fs)
{
    for (auto& f : fs)
        f();
}
 
void plain_old_func()
{
    std::cout << "I'm an old plain function" << std::endl;
}
 
class functor final
{
public:
    void operator()() const
    {
        std::cout << "I'm a functor" << std::endl;
    }
};
 
int main()
{
    std::vector<std::function<void ()>> x;
    x.push_back(plain_old_func);
     
    functor functor_instance;
    x.push_back(functor_instance);
    x.push_back([] ()
    {
        std::cout << "HI, I'm a lambda expression" << std::endl;
    });
     
    execute(x);
}

As it can be seen, in this declaration:

std::vector<std::function<void ()>> x;

a vector of functions is being declared. The void () part means that the functions stored there do not receive any arguments and do not return anything (i.e., they have void as the return type). If programmers wanted to define a function that receives two integers and returns an integer, they could declare std::function as:

int my_func(int a, int b) { return a + b; }
 
function<int (int, int)> f = my_func;

The standard library also includes a function called std::bind. std::bind is a template function that returns a std::function object which, as the name suggests, binds a set of arguments to a function.

In the first code example, the functions stored in the vector do not receive any arguments, but programmers might want to store a function that accepts arguments in the same vector. They can do this using std::bind.

Having this function:

void show_text(const std::string& t)
{
    std::cout << "TEXT: " << t << std::endl;
}

How can it be added to the vector of functions in the first code listing (if even possible, because they have different signatures)? It can be added like this in the main() function:

std::function<void ()> f = std::bind(show_text, "Bound function");
x.push_back(f);

The code above shows that std::bind takes a pointer to a function (it can also be a lambda expression or a functor) and a list of parameters to pass to that function. As a result, std::bind returns a new function object with a different signature because all the parameters for the function have already been specified.

For example, this code:

#include <functional>
#include <iostream>
  
int multiply(int a, int b)
{
    return a * b;
}
 
int main()
{
    using namespace std::placeholders;

    auto f = std::bind(multiply, 5, _1);
    for (int i = 0; i < 10; i++)
    {
        std::cout << "5 * " << i << " = " << f(i) << std::endl;
    }

    return 0;
}

demonstrates another usage of std::bind. The first parameter is a pointer to the multiply function. The second parameter is the value passed as the first argument to multiply. The third parameter is called a “placeholder.” A placeholder specifies which parameter in the bound function will be filled by a runtime argument. Inside the for loop, f is called with only one parameter, and the second argument is provided dynamically.

Thanks to placeholders, even the order of arguments can be modified. For example:

#include <functional>
#include <string>
#include <iostream>
  
void show(const std::string& a, const std::string& b, const std::string& c)
{
    std::cout << a << "; " << b << "; " << c << std::endl;
}
 
int main()
{
    using namespace std::placeholders;

    auto x = std::bind(show, _1, _2, _3);
    auto y = std::bind(show, _3, _1, _2);
    auto z = std::bind(show, "hello", _2, _1);
     
    x("one", "two", "three");
    y("one", "two", "three");
    z("one", "two");
     
    return 0;
}

The output is:

one; two; three
three; one; two
hello; two; one

std::bind can also be used to wrap a method of a given object (i.e., an already instantiated one) into a function. For example, if programmers want to wrap the say_something method from the following struct:

struct Messenger
{
    void say_something(const std::string& msg) const
    {
        std::cout << "Message: " << msg << std::endl;
    }
};

into a std::function declared as follows:

using my_function = std::function<void (const std::string&)>;

The call to std::bind would look like this:

Messenger my_messenger; /* an actual instance of the class */

my_function 
    a_simple_function = std::bind(
        &Messenger::say_something /* pointer to the method */,
        &my_messenger, /* pointer to the object */,
        std::placeholders::_1 /* placeholder for the first argument in the method, as usual */
);

a_simple_function("Hello"); // will invoke the method Messenger::say_something on the object my_messenger

27 thoughts on “C++: std::function and std::bind

  1. wow.. this is the most lucid explanation of c++11 concepts I have seen . Thanks for it.

  2. I’d nailed down std::function and lambdas, but struggled with the std::bind syntax and what _1 actually meant. This is by far the clearest explanation I’ve found so far. Good work sir. :)

  3. Probably the best and simples explanation on the net! Thanks.

    However. you *should* add info about the member function invocation using bind.
    The fact that you can bind the hidden ‘this’ argument and transform a member function into a regular one!

  4. this article was very useful in understanding the use of the placeholders with std::bind. I’d like to point that there is an little error in line (The second parameter is called a “placeholder”), as it should read (The third parameter …..)

    Thanks!

  5. Very good explanation. I didn’t understand anything about bind when I read about it in the C++ Primer (5th Edition) book. But this made it all clear to me!

  6. very good articles especially for beginner of c++11 like me. Thanks a lot.

    can you also explain one doubt

    1| function f = bind(show_text, “Bound function”);
    2| x.push_back(f);

    function
    function-type given to std::function is type-mismatched at line 1?
    If yes, then how we can insert it into vector.

    can you explain this please?

    Again thanks a lot for this concise and clear articles.

    1. Vivek, thanks for your nice comments.

      I reviewed my code in the example and void() is the right parameterized type for the bound function. Remember, bind() “hard codes” the “Bound function” and thus, there is no need to pass any parameter anymore. “Bind” does something like: auto f = []() { show_text(“Bound function”); };

  7. Cool, so you can achieve currying like in functional programming languages ? Even more flexible with the potential reordering of parameters. Is that right ?

  8. Thanx a lot… This will help me Finish my 1st Assignment of the course “High End Simulation Practice:-)”

  9. std::bind receives a pointer to a function. Can you explain with an example for a use case where there is a function which in turn usage std::bind to bind another function. This another function is not fixed and this can be a variable. So need the syntax of a function which receives a pointer to a function which is passed to std::bind.

  10. Wow Thank you so much for clearing the doubts and Such Nice explanation. God Bless u.

Leave a reply to pavanto Cancel reply