From http://cunsh.ycool.com/post.1946109.html
Chapter 2 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. You can't see it. Here we only write down its usage:
9.1 for common functions
Assume that the function fun () is as follows:
Void fun (int x, int y ){
Cout <x <"," <Y <Endl;
}
Now let's look at how to bind parameters to bind them.
For common functions like fun, if fun has N parameters, bind requires n + 1 parameter: Address of the original function and N parameters to be bound.
1st usage:
Bind all parameters to the original function fun
Boost: BIND (& fun, 3, 4) // The real parameter table of BIND is: Address of the function to be bound, bind to the first parameter value of fun, the second parameter value...
// The number of parameters required for fun.
Bind 3 and 4 as parameters to the fun function.
Because all parameters are bound, now we call the function object returned by BIND:
Boost: BIND (& fun, 3, 4) (); // No parameter.
The output is 3, 4.
2nd usage:
Bind a part of parameters to the original function fun
Boost: BIND (& fun, 3, _ 1) // The real parameter table of BIND is: the address of the function to be bound, which must be bound to the first parameter value of fun, then pay attention
// Because we do not intend to bind 2nd parameters to fun (that is, we want to specify the value of this parameter when calling the returned functor)
// Here _ 1 is used for placeholder. Here _ 1 represents the 1st parameters of the real parameter table when the new function object is called.
// Similarly, placeholders such as _ 2 _ 3 will be used below.
Here, only fun is bound with the first parameter 3. Therefore, when calling the function object returned by bind, you need:
Boost: BIND (& fun, 3, _ 1) (4); // This 4 will replace the _ 1 placeholder.
Output 3, 4
Similarly, 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. As mentioned above.
Therefore, it binds the 1st and 2nd parameters of the real parameter table of the new function object when calling to the fun function.
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.
Output 4, 3
Similarly, boost: BIND (& fun, _ 1, _ 1) (3); // 3 will replace the _ 1 placeholder
Outputs 3, 3
This is true for common functions. For function objects, such:
Struct func {
Void operator () (int x ){
Cout <x <Endl;
}
} F;
When binding, you may need to specify the type of the returned value:
Boost: bind <void> (F, 3) (); // specifies the type of the returned value void.
9.2 for non-static member functions
Assume that:
Struct {
Void func (int x, int y ){
Cout <x <"," <Y <Endl;
}
};
A;
A * pA = new A; // pointer
Boost: shared_ptr <A> ptr_a (PA); // smart pointer.
Now you need to bind a non-static member function like a: func.
If a: func has N parameters, bind must have n + 2 parameters: pointer to the member function fun, bound to the object of this, N parameters.
For example:
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. For example:
Boost: BIND (& A: func, _ 1, 3, 4) (ptr_a); // output 3, 4
It can be seen that, no matter whether the 2nd parameters passed to bind are objects, object pointers, or smart pointers, the BIND function works properly.
9.3 bind nesting
There is a class as follows:
Class personal_info {
String name _;
Int age _;
Public:
Int get_age ();
String name ();
};
Vector <personal_info> VEC;
...
Sort VEC now. 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), // _ 1 placeholder is the first parameter when the comparison function is called in sort.
Boost: BIND (& personal_info: age, _ 2); // _ 2 placeholder is the second parameter used to call the comparison function in sort.
9.4 function combination
Assume that:
Vector <int> ints;
...
We want to use STD: count_if () to calculate the number of ints values greater than 5 and <= 10. In general code, we usually need to write a function to implement this predicate:
If (I> 5 & I <= 10 )...
Now you can use bind:
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 bind to member variables
Include:
Map <int, string> my_map;
My_map [0] = "Boost"; my_map [1] = "bind ";
Now we need to output the second members of all elements. That is, to output these strings. The print function is 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)
)
);
Khan... I don't know the source code of bind. I don't know how to implement these functions. I have to wait for <boost source code analysis>.
Note:
(The following is supplemented by June 3)
The function object returned by boost: BIND () will save the real parameters to be bound, and will always copy a copy to save as a value ..
This mainly takes into account the life cycle of the bound real parameters.
But this is not always what we expect. For example, sometimes we want it to save pointers or references:
Function:
Void F (Int & X) {++ X ;}
Then:
Int n = 0;
BIND (& F, n) (); // We want n = 1. but actually this is not...
To avoid copying such an object, save the reference semantics of the real parameter for the function object to be obtained by BIND. You can:
Use boost: ref () or boost: CREF () such
BIND (& F, ref (N) (); // OK, after execution, n = 1
To bind an object to its member functions, for example:
A;
BIND (& A: Fun, a); // stores the copy of object.
To avoid this copy, you can also:
BIND (& A: Fun, & A); // use a pointer. You can use an object or a pointer. Instead, use a pointer to avoid copying objects.
Note: (Add the following to April 1, June 10)
The first parameter of BIND () -- bound function -- is not evaluated. For 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); // you can call this method to implement _ 1 (5. but this is not the case!
The correct method is to use the boost: Apply template (from boost/bind/apply. HPP ).
Apply is also a function object. Its functions are as follows:
Apply <void> A; // The template parameter is the return value type of the function object.
A (x); // call X ();
A (x, y); // call X (y );
A (x, y, z); // call X (Y, Z );
Therefore, the wrong BIND should be written as follows:
STD: for_each (V. Begin (), V. End (), BIND (apply <void> (), _ 1, 5 ));