C++ | std::bind(), the forwarding call wrapper

C++11 introduced the std::bind() to create a forwarding call wrapper for a function associated argument values. We can bind a function with its parameters to get a callable object. We can call that object anytime later. In fact, calling that callable object and the actual function with the bound parameters are the same. Let’s take an example.

#include<iostream>
#include <functional>

void func(int a, int b) {
    std::cout << (a - b) << std::endl;
}

int main() {
    auto ob = std::bind(func, 5, 4);

    ob();
}
$ g++ -o test test.cpp 
$ ./test 
1

We have a function, func(), that prints the difference between the two input arguments.

In the main(), we bound this function with parameters 5 and 4. We got the callable object, ob. The function is not called yet. We can call this function with the already bound parameters anytime by calling ‘ob‘. We did that in the next line and got the expected result.

You might be wondering why we need to bind a function while we can call the function directly.

Let’s consider some use cases where std::bind() could be beneficial.

Making Some Function Parameters Optional

We can make one or more function parameters optional combining std::bind() with std::placeholders. To make the first parameter optional, we can bind it with some fixed value and leave the second parameter with a placeholder. In time of calling the object, we’ll have to specify only the second parameter.

#include<iostream>
#include <functional>

void func(int a, int b) {
    std::cout << (a - b) << std::endl;
}

int main() {
    auto ob = std::bind(func, 5, std::placeholders::_1);

    ob(3);
}
$ g++ -o test test.cpp 
$ ./test 
2

So, here we made the first parameter, a, optional with default value 5.

We could achieve similar things by specifying default values in time of function definition. It would have made the parameters optional.

But here we have two clear benefits.

  1. We made the first argument optional and the second one mandatory. It is not possible by specifying default values during function definition. To make the first argument optional, we’ll have to make the all following arguments optional. It will be problematic if we have lot of parameters.
  2. We made the default value 5 for the first parameter. We can easily have another variation with default value 10 for the same parameter.
#include<iostream>
#include <functional>

void func(int a, int b) {
    std::cout << (a - b) << std::endl;
}

int main() {
    auto ob = std::bind(func, 5, std::placeholders::_1);
    auto ob1 = std::bind(func, 10, std::placeholders::_1);

    ob(3);
    ob1(3);
}
$ ./test
2
7

It is not possible without std::bind(). Similarly, we can have different type of variations if we have more input parameters of the function.

Defining Works for Asynchronous Operations

Let’s assume that our function is a time consuming one – it has operations like reading from network or some I/O device. We can define multiple works by associating different input arguments and then schedule them for asynchronous execution.

In this article, we have an example of schedule asynchronous works using boost:asio framework. There we used similar binding function boost::bind().

Author: Srikanta

I write here to help the readers learn and understand computer programing, algorithms, networking, OS concepts etc. in a simple way. I have 20 years of working experience in computer networking and industrial automation.


If you also want to contribute, click here.

Leave a Reply

Your email address will not be published. Required fields are marked *

0
0
0
0
0
0