Bind-boost
Header file: boost/bind.hpp
Bind is a set of overloaded function templates.
Used to bind certain parameters to a function (or function object).
The return value of BIND is a function object.
Its source file is too long. Can't look down. Here, just write down its usage:
9.1 For normal functions
If there is a function fun () as follows:
void Fun (int x, int y) {
cout << x << "," << y << Endl;
}
Now let's see how to bind parameters with bind.
For ordinary functions such as fun. If fun has n parameters. Bind requires N+1 parameters: the address of the original function and the n parameters to bind.
1th usage:
Bind all parameters to the original function fun
Boost::bind (&fun, 3, 4)//Bind's argument list is: The address of the function to bind, the first parameter value bound to the fun, the second parameter value ...
How many parameters are there, and how many are available here.
Indicates that 3 and 4 are bound to the fun function as arguments.
Because all parameters are bound. Now we call the function object returned by bind:
Boost::bind (&fun, 3, 4) (); No parameters.
It will output 3, 4
2nd usage:
Bind some parameters to the original function fun
boost::bind (&fun, 3, _1) //Bind's argument table in order or: the address of the function to bind To the first parameter value of the fun, and then note
//because we're not going to bind the 2nd argument to fun ( That is, we want to specify the value of this parameter when the returned functor is called)
//so this is where _1 is used to take the place. The _1 here Represents the time when the new function object is being invoked. The 1th parameter of the argument table.
//also uses placeholders such as _2 _3 below.
only the first parameter 3 is bound to fun here. So when calling the function object returned by BIND. Required:
boost::bind (&fun, 3, _1) (4); //This 4 will replace the _1 placeholder.
Output 3, 4
The same boost::bind (&fun, _1, 3) (4);
Output 4, 3
3rd usage:
Do not bind any parameters to fun
Boost::bind (&fun, _1, _2)//_1 _2 are placeholders. It has been said above.
So it binds the new function object to the fun function in the 1th and 2nd arguments of the argument table at the time of invocation.
Boost::bind (&fun, _1, _2) (3, 4); 3 will replace the _1 placeholder, and 4 will replace the _2 placeholder.
Output 3, 4
Similarly boost::bind (&fun, _2, _1) (3, 4); 3 will replace the _1 placeholder, and 4 will replace the _2 placeholder.
Will output 4, 3
Similarly boost::bind (&fun, _1, _1) (3); 3 will replace the _1 placeholder
Will output 3, 3
For normal functions, that's all. For a function object. Such as:
struct Func {
void operator () (int x) {
cout << x << Endl;
}
} F;
When binding, you may want to indicate the type of the return value:
Boost::bind<void> (F, 3) (); Indicates the type of return value void
9.2 For non-static member functions
If there are:
struct A {
void func (int x, int y) {
cout << x << "," << y << Endl;
}
};
A;
A * pa = new A; Pointer
Boost::shared_ptr<a> Ptr_a (PA); Smart pointers.
Now you want to bind to a non-static member function such as A::func.
If A::func has n arguments, bind must have n+2 parameters: A pointer to the member function fun, the object bound to this, n parameters.
Such as:
Boost::bind (&a::func, A, 3, 4) (); Output 3, 4
Boost::bind (&a::func, PA, 3, 4) (); Output 3, 4
Boost::bind (&a::func, Ptr_a, 3, 4);//Output 3, 4
You can also use placeholders such as _1. Such as:
Boost::bind (&a::func, _1, 3, 4) (ptr_a);//Output 3, 4
can be seen. Regardless of the 2nd argument passed to bind is an object. The object pointer. or a smart pointer. The BIND function works correctly.
9.3 Bind Nesting
There is a class below. Record person's information:
Class Personal_info {
String name_;
int Age_;
Public
int Get_age ();
String name ();
};
Vector<personal_info> VEC;
...
Now you want to sort the VEC. You can use the BIND function to make a comparison predicate
Std::sort (
Vec.begin (),
Vec.end (),
Boost::bind (
Std::less<int> (),
Boost::bind (&personal_info::age,_1), the//_1 placeholder is the first parameter in sort when a comparison function is called.
Boost::bind (&personal_info::age,_2)); The _2 placeholder is the second parameter in sort when a comparison function is called.
9.4 function Combinations
If there are:
Vector<int> ints;
...
Want to use STD::COUNT_IF () to find out how many of the INTs is >5 and <=10. This is usually written in regular code to implement this predicate:
if (i>5 && i<=10) ...
Now with bind you can:
Std::count_if (
Ints.begin (), Ints.end (),
Boost::bind (
Std::logical_and<bool> (),
Boost::bind (Std::greater<int> (), _1,5),
Boost::bind (Std::less_equal<int> (), _1,10));
9.5 Binding to member variables
Yes:
Map<int, string> My_map;
My_map[0]= "Boost"; my_map[1]= "Bind";
Now you want to output the second members of all elements. That is, the output of these strings. The printing functions are as follows:
void print_string (const string& s) {
Std::cout << s << '/n ';
}
You can:
For_each (
My_map.begin (),
My_map.end (),
Boost::bind (
&print_string,
Boost::bind (&std::map<int,std::string>::value_type::second,_1)
)
);
Sweat... Can not understand the source of bind. I do not know how to achieve these functions. Can only wait <<boost source analysis >> came out.
Attention:
(The following is on June 3, 08)
The function object returned by Boost::bind () saves the argument to bind. And it always copies a copy to save it in a value way.
This is primarily due to the lifetime of the bound arguments.
But that's not always what we're looking for. For example, sometimes we want it to save pointers or references:
There are functions:
void f (int & x) {++x;}
And then:
int n = 0;
Bind (&f, N) (); We want to n==1. But not really.
To avoid this object duplication. And the function object to bind gets is to save the argument's reference meaning. OK:
Use Boost::ref () or boost::cref () such as
Bind (&f, ref (n)) (); OK, after execution n==1
If you are binding an object to its member function. Such as:
A;
Bind (&a::fun, A); A copy of the A object is saved.
To avoid this copy. In addition to the ref () mentioned above, you can also:
Bind (&a::fun, &a); With a pointer. You can use both objects and pointers anyway. With pointers you can avoid the problem of copying objects.
Note: (The following is for June 10)
The first parameter of bind ()--The bound function--is not evaluated. The following example:
typedef void (*PF) (int);
Std::vector<pf> v; There are some function pointers in V.
Std::for_each (V.begin (), V.end (), Bind (_1, 5)); Want to achieve _1 (5); Such a call. But it doesn't work!
The correct approach is to use the boost::apply template (from BOOST/BIND/APPLY.HPP).
Apply is also a function object. Its function is as follows:
Apply<void> A; The template parameter is the return value type of the function object.
A (x); Equivalent to calling X ();
A (x, y); Equivalent to calling x (y);
A (x, y, z); Equivalent to calling X (Y, z);
So the wrong bind should be written as:
Std::for_each (V.begin (), V.end (), Bind (Apply<void> (), _1, 5));