Assign Binding Function

I am learning asio programming of the C ++ Boost library. And I came across many examples that use the bind () function, which has a function pointer as an argument.

I could not understand the use of the bind () function. And so I hardly understand programs that use boost libraries asio.

I am not looking for any code here. I just want to know how to use the bind () function or any equivalent function of it. Thanks in advance.

+5
source share
3 answers

From cppreference

The bind function template creates a forwarding wrapper for f. Calling this shell is equivalent to calling f with some arguments associated with the arguments.

Check the example below showing the binding

#include <iostream> #include <functional> using namespace std; int my_f(int a, int b) { return 2 * a + b; } int main() { using namespace std::placeholders; // for _1, _2, _3... // Invert the order of arguments auto my_f_inv = bind(my_f, _2, _1); // 2 args b and a // Fix first argument as 10 auto my_f_1_10 = bind(my_f, 10, _1); // 1 arg b // Fix second argument as 10 auto my_f_2_10 = bind(my_f, _1, 10); // 1 arg a // Fix both arguments as 10 auto my_f_both_10 = bind(my_f, 10, 10); // no args cout << my_f(5, 15) << endl; // expect 25 cout << my_f_inv(5, 15) << endl; // expect 35 cout << my_f_1_10(5) << endl; // expect 25 cout << my_f_2_10(5) << endl; // expect 20 cout << my_f_both_10() << endl; // expect 30 return 0; } 

You can use bindings to control the existing order of function arguments, or to correct some arguments. This can be especially useful in container and stl algorithms, where you can pass an existing library function whose signature matches your requirement.

For example, if you want to convert all of your counterparts in a container to degree 2, you can simply do something like:

 std::transform(begin(dbl_vec), end(dbl_vec), begin(dbl_vec), std::bind(std::pow, _1, 2)); 

Live example here

+5
source

The tasks that you submit to the boost::asio service must be invokable with null arguments so that the service can store and invoke them when it has spare resources (i.e. unoccupied threads). Let's say you want it to call the void purr(int kitty) function, to pass this to the service in a format that it can work with, you need to bind the kitty argument to the purr function. This will give you an object that can be called using () with no arguments that you can provide to the service.

Of course, with C ++ 11 and lambda functions, the best way to do it now is to do io_service.post([&](){ purr(3); }); and do not use bind at all.

+2
source

This allows you to bind (or "bind") your own data using the function you want to call the library, without a library that needs to know anything about your data.

Since you are looking at Boost.Asio, look at the tutorial for binding arguments to a handler . They have a function that they want to use as a handler, for which they need pointers to their own data, the timer itself and the counter:

 void print(const boost::system::error_code& /*e*/, boost::asio::deadline_timer* t, int* count) { // ... } 

The async_wait timer async_wait calls the user-called function when the timer expires; but gives only the first of these arguments. The handler has the form

 void handler( const boost::system::error_code& error // Result of operation. ); 

Thus, we can use bind to convert our function (wanting three arguments) to a unit that wants only one argument, by specifying values โ€‹โ€‹that should be passed as the other two:

 t.async_wait(boost::bind(print, boost::asio::placeholders::error, &t, &count)); 

The result of bind is a function object (i.e. an object of type class that overloads the function call operator() , operator() ), which in this case takes one argument. The placeholders::error argument says that the first argument is still the argument of the new function type; the other two arguments are assigned the values &t and &count when calling a new function. Therefore, if we ourselves called it:

 auto f = boost::bind(print, boost::asio::placeholders::error, &t, &count) f(some_error); 

this will have the same effect as calling the original function with these arguments:

 print(some_error, &t, &count); 

Now that the timer expires, our function is called with the arguments we provided, without the Asio library, which should know anything about them.

+1
source

Source: https://habr.com/ru/post/1208421/


All Articles