Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > how second and first arg are binded?

Reply
Thread Tools

how second and first arg are binded?

 
 
Hunter Hou
Guest
Posts: n/a
 
      08-09-2004
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


 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-09-2004
Hunter Hou wrote:
> 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?


All those elements of the standard library are templates. Please take
a look at the headers where those things are defined, it should be easy
enough to understand. Whenever in doubt, use the source.

V
 
Reply With Quote
 
 
 
 
AlesD
Guest
Posts: n/a
 
      08-10-2004
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
 
Reply With Quote
 
Hunter Hou
Guest
Posts: n/a
 
      08-10-2004

>
> 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.


Thanks! Ales. I understand what you said since you are talking about
function with 2 args(acturally i read source code of bind2nd() ). What i
didn't figure out is how bind2nd works with mem_fun() because member
function has one arg while bind2nd() deals with two args function.

Could you give an example like what you did above?

Regards,
Hunter
 
Reply With Quote
 
Hunter Hou
Guest
Posts: n/a
 
      08-10-2004

>> 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?

>
>
> All those elements of the standard library are templates. Please take
> a look at the headers where those things are defined, it should be easy
> enough to understand. Whenever in doubt, use the source.



Yes. This question came out after I read the source code. bind2nd( arg1,
arg2) .arg1 is a binary functor, but rotate( int ) only has one arg.

My udnerstanding of above code is
bind2nd( mem_fun( &Shape::rotate ), angle ) ( obj ),

next is
mem_fun( &Shape::rotate ) ( obj, angle )

but what's next? How is obj handled since member function has only one
argument?

Hope i can explain my question clearly.

thanks,
Hunter
===
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      08-10-2004

"Hunter Hou" <(E-Mail Removed)> wrote in message
news:cfa3m5$(E-Mail Removed)...
>
> >> 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?

> >
> >
> > All those elements of the standard library are templates. Please take
> > a look at the headers where those things are defined, it should be easy
> > enough to understand. Whenever in doubt, use the source.

>
>
> Yes. This question came out after I read the source code. bind2nd( arg1,
> arg2) .arg1 is a binary functor, but rotate( int ) only has one arg.
>
> My udnerstanding of above code is
> bind2nd( mem_fun( &Shape::rotate ), angle ) ( obj ),
>
> next is
> mem_fun( &Shape::rotate ) ( obj, angle )
>
> but what's next? How is obj handled since member function has only one
> argument?
>
> Hope i can explain my question clearly.
>
> thanks,
> Hunter
> ===


Shape::rotate has only one arg but mem_fun( &Shape::rotate ) is a functor
with two args. The first argument to mem_fun( &Shape::rotate ) is a pointer
to the shape you want to rotate, then second arg is the angle.

john



 
Reply With Quote
 
Daniel T.
Guest
Posts: n/a
 
      08-10-2004
In article <cfa3m5$(E-Mail Removed)>,
Hunter Hou <(E-Mail Removed)> wrote:

> >> 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?

> >
> >
> > All those elements of the standard library are templates. Please take
> > a look at the headers where those things are defined, it should be easy
> > enough to understand. Whenever in doubt, use the source.

>
>
> Yes. This question came out after I read the source code. bind2nd( arg1,
> arg2) .arg1 is a binary functor, but rotate( int ) only has one arg.
>
> My udnerstanding of above code is
> bind2nd( mem_fun( &Shape::rotate ), angle ) ( obj ),
>
> next is
> mem_fun( &Shape::rotate ) ( obj, angle )
>
> but what's next?


inside mem_fun( &Shape::rotate ) ( obj, angle ) is

obj->rotate( angle )

You can tell this because of the source of mem_fun1_t:

template <class _Ret, class _Tp, class _Arg>
class mem_fun1_t : public binary_function<_Tp*,_Arg,_Ret> {
public:
explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) {}
_Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); }
private:
_Ret (_Tp::*_M_f)(_Arg);
};
 
Reply With Quote
 
AlesD
Guest
Posts: n/a
 
      08-10-2004
Hunter Hou napsal(a):
>
> Thanks! Ales. I understand what you said since you are talking about
> function with 2 args(acturally i read source code of bind2nd() ). What i
> didn't figure out is how bind2nd works with mem_fun() because member
> function has one arg while bind2nd() deals with two args function.
>
> Could you give an example like what you did above?
>
> Regards,
> Huntervoid rotate_all( list<Shape*>& ls, int angle )


OK, let's thake it step-by-step:

mem_fun( &Shape::rotate ) will create function (it is actually functor,
but it does not matter) which takes two arguments. First argument is
instance of Shape, second is angle - or more precisely Shape::rotate
argument. The function then calls member Shape::rotate with angle as
it's argument. You can imagine it as follows:

int call_shape_member(Shape& my_shape, int angle)
{
return my_shape.rotate(angle);
};

(I suppose that Shape::rotate argument type is int as well as it's
return type).

So you have non-member function which takes Shape& and int. Next you
convert it to unary function by binding the second parameter to constant.

bind2nd( mem_fun( &Shape::rotate ), angle)

Now you have unary function which:

1) takes Shape& as argument
2) call Shape::rotate with angle as argument

You apply it to all elements of list

for_each( ls.begin(), ls.end(), bind2nd( mem_fun( &Shape::rotate ),
angle ));

And that's it. Simple.

BTW: Are you sure about the list<Shape*>? Shouldn't it be list<Shape>?

Ales
 
Reply With Quote
 
AlesD
Guest
Posts: n/a
 
      08-10-2004
AlesD napsal(a):
> BTW: Are you sure about the list<Shape*>? Shouldn't it be list<Shape>?


Hmm - probably not.

A.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How to pass a multiline arg to exec('some.exe arg')? n00m Python 5 05-05-2008 02:58 PM
the first arg to super() must be a type, not a class obj? metaperl Python 4 09-08-2006 08:38 AM
Trouble with setTimeout(arg, arg) nat.hourt@gmail.com Javascript 7 11-12-2005 05:13 PM
&first arg of a union or struct RoSsIaCrIiLoIA C Programming 1 06-24-2004 05:16 PM



Advertisments