From:http://greyforest.blog.sohu.com/152084205.html
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. I can't see it anymore. Here is only a note of its usage:
9.1 For ordinary 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 the parameters to it with bind.
For ordinary functions such as fun. If the fun has n parameters. Then bind requires N+1 parameters: the address of the original function and n the parameters to bind.
The 1th way to use:
Bind all parameters to the original function fun
The argument list for Boost::bind (&fun, 3, 4)/bind is: The address of the function to bind to, the first parameter value bound to fun, and the second parameter value ...
Fun How many parameters are there to provide.
Indicates that 3 and 4 are bound to the fun function as parameters.
Because all of the 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:
to the original function fun a part of the parameters
boost::bind (&fun, 3, _1) //Bind's argument list in order or: the function to bind Address, to bind to the first parameter value of fun, and then note the
//because we do not intend to bind the 2nd argument to fun ( That is, we want to specify the value of this parameter when calling the returned functor
//so use _1 here to occupy the place. The _1 here Represents the new function object when it is invoked. The 1th parameter of the argument table.
//also uses placeholders such as _2 _3 below.
only the first parameter 3 is bound for fun. So when you call the function object returned by BIND. Required:
boost::bind (&fun, 3, _1) (4); //This 4 replaces the _1 placeholder.
Output 3, 4
Same boost::bind (&fun, _1, 3) (4); &NBSP
Output 4, 3
The 3rd way to use:
Do not bind any parameters to fun
Boost::bind (&fun, _1, _2)//_1 _2 are placeholders. It has already been said.
So it is the binding of the new function object to the fun function at the 1th and 2nd parameters of the argument table at the time of the call.
Boost::bind (&fun, _1, _2) (3, 4); 3 replaces the _1 placeholder, and the 4 replaces the _2 placeholder.
Output 3, 4
Empathy Boost::bind (&fun, _2, _1) (3, 4); 3 replaces the _1 placeholder, and the 4 replaces the _2 placeholder.
Will output 4, 3
Empathy Boost::bind (&fun, _1, _1) (3); 3 will replace the _1 placeholder
Will output 3, 3
For ordinary functions, that's all. For a function object. Such as:
struct Func {
void operator () (int x) {
cout << x << Endl;
}
} F;
You may want to indicate the type of the return value when binding:
Boost::bind<void> (F, 3) (); Indicates the type void of the return value
9.2 for non-static member functions
If there are:
struct A {
void func (int x, int y) {
cout << x << "," << y << Endl;
}
};
A A;
A * pa = new A; Pointer
Boost::shared_ptr<a> Ptr_a (PA); Smart pointers.
Now you want to bind to non-static member functions such as A::func.
If A::func has n parameters, bind must have n+2 arguments: A pointer to a member function fun, an object bound to this, n arguments.
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. Whether the 2nd parameter passed to bind is an object. The object pointer. or a smart pointer. The BIND function works correctly.
9.3 Bind Nesting
There are 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 do a comparison predicate with the BIND function
Std::sort (
Vec.begin (),
Vec.end (),
Boost::bind (
Std::less<int> (),
Boost::bind (&personal_info::age,_1),//_1 placeholder is the first argument in sort when the comparison function is invoked.
Boost::bind (&personal_info::age,_2))); The _2 placeholder is the second parameter when the comparison function is called in sort.
9.4 function Combination
If there are:
Vector<int> ints;
...
Want to use STD::COUNT_IF () to find out how much of the ints is >5 and <=10. This is usually done in regular code by writing a function 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 the elements. That is, the output of these strings. The print 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't read the source code of BIND. I do not know how to achieve these functions. Can only wait for <<boost source analysis >> out.
Attention:
(The following to be filled on June 3, 08)
The function object returned by Boost::bind () holds the arguments to bind. And always copy a value to save it.
This is mainly due to the lifetime of the bound arguments.
But that's not always what we expect. For example, sometimes we want it to save pointers or references:
There are functions:
void f (int & x) {++x;}
Then
int n = 0;
Bind (&f, N) (); We hope to n==1. But not really ...
To avoid this kind of object duplication. And to bind the function object to save the argument meaning of the actual argument. OK:
Use Boost::ref () or boost::cref () as
Bind (&f, ref (n)) (); OK, after execution n==1
If you are binding an object to its member function. Such as:
A A;
Bind (&a::fun, A); A copy of object A is saved.
To avoid this copy. In addition to the ref () mentioned above, you can also:
Bind (&a::fun, &a); with pointers. You can use both objects and pointers anyway. With pointers, you can avoid the problem of copying objects.
Note: (Following up to 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 realize _1 (5); Such a call. But that's not going to happen!
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));