Hunter Hou napsal(a):
hello,
I'm reading <the C++ programming language>, here's a question for bind2nd.
Who can help explain what on earth bind2nd is working?
...
void rotate_all( list<Shape*>& ls, int angle )
{
for_each( ls.begin(), ls.end(), bind2nd( mem_fun( &Shape::rotate ),
angle ));
}
This code is very easy to understand, but when i tried to use bind2nd and
mem_fun() source code to see what's going on here, I don't understand how
"angle" is binded as second argument? And how the first arg is binded as
Shape* under the condition of op(x, arg2) of binder2nd?
Thanks,
Hunter
Hello,
short explaintation:
bind2nd convert function which takes two arguments into function which
takes only 1 argument and call the original with 2nd argument replaced
by constant.
definitions:
If f is an object of class binder2nd<AdaptableBinaryFunction>, then f(x)
returns F(x, c), where F is an object of class AdaptableBinaryFunction
and where c is a constant. Both F and c are passed as arguments to
binder2nd's constructor.
example:
Suppose you have function which takes two arguments - say:
void my_function(my_type& my_object, int some_number);
Then you have vector of my_type objects:
vector<my_type> my_vector(10);
and you want to apply my_function() to all bojects in the vector with
constant second argument (equal to 5). There is STL function for_each
which can help, but it has chatch: it takes only unary function so you
have to:
a) define new version of your function
void my_function2(my_type& my_object) {
my_function(my_object, 5);
}
This has the disadvantage that you can't change the value of second
parameter. To overcome this you can also:
b) define functor which uses your function
class my_functor
{
private:
int second_argument;
public:
my_functor(int init_second_argument)
: second_argument(init_second_argument) {};
operator()(my_type& first_argument)
{
my_function(first_argument, second_argument);
};
}
and use it:
my_functor(5) f;
f(my_object); // this equals to: my_function(my_object, 5);
binder2nd does actually same thing, but can save you the typing...
3) Use function adaptor binder2nd
which will turn your function into unary function "on-line"
bind2nd(my_function(), 5) (my_object);
^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^
new functor created argument
Compare the final results:
1) ------------------
void my_function(my_type& my_object, int some_number);
void my_function2(my_type& my_object) {
my_function(my_object, 5);
}
int main()
{
vector<my_type> my_vector(10);
for_each(my_vector.begin(), my_vector.end(), my_function2());
}
2) ------------------
void my_function(my_type& my_object, int some_number);
class my_functor
{
private:
int second_argument;
public:
my_functor(int init_second_argument)
: second_argument(init_second_argument) {};
operator()(my_type& first_argument)
{
my_function(first_argument, second_argument);
};
}
int main()
{
vector<my_type> my_vector(10);
for_each(my_vector.begin(), my_vector.end(), my_functor(5));
}
3) ------------------
void my_function(my_type& my_object, int some_number);
int main()
{
vector<my_type> my_vector(10);
for_each(my_vector.begin(), my_vector.end(),
bind2nd(my_function(), 5));
}
---------------------
For more information see
http://www.sgi.com/tech/stl/binder2nd.html
Have a nice day. Ales