How does bind1st() work in this case?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • wenmang

    How does bind1st() work in this case?

    Hi, all:
    I am reading Herb Sutter's article:
    Borrow independently with no guarantor loans from £100-£2,500. Soft credit check won't affect your score. No fees from Sunny. Apply online in minutes.

    I have trouble to understand for following lines:

    class Subject {
    // ...
    public:
    virtual void Attach( function<void (Subject*)> o ) {
    obs_.push_back( o); } --Line1
    virtual void Detach( function<void (Subject*)> o ) { /* ... */ }
    virtual void Notify() {
    for( list<function<v oid (Subject*)> >::iterator i = obs_.begin();
    i != obs_.end(); ++i )
    (*i)( this );
    }
    private:
    list<function<v oid (Subject*)> > obs_;
    };

    class ClockTimer : public Subject { // as before
    // ...
    void Tick() {
    // ... timekeeping logic...
    Notify(); // every so often, tick
    }
    };

    class DigitalClock : /*...*/ public Observer { // still works
    // ...
    public:
    DigitalClock( ClockTimer* t ) : timer_(t)
    { timer_->Attach( bind1st( mem_fun( &DigitalClock:: OnUpdateOf ),
    this ) ); } --Line2
    ~DigitalClock()
    { timer_->Detach( bind1st( mem_fun( &DigitalClock:: OnUpdateOf ),
    this ) ); }
    void OnUpdateOf( Subject* timer ) { /* query timer and redraw */ }
    private:
    ClockTimer* timer_;
    };

    Here are my questions:
    1. mem_fun() generates the unary functor, but bind1st() takes binary
    function as its 1st argument, how does Line2 work?
    2. Could you please provide stepwise explanation how Line2 being
    expanded to fit member function signature of Attach(function <void
    (Subject*)> )?
    3. is "this" on Line2 a DigitalClock*? DigitalClocl* is not Subject*
    for Attach(), isn't?

    Thanks.
  • Victor Bazarov

    #2
    Re: How does bind1st() work in this case?

    "wenmang" <wenmang@yahoo. com> wrote...[color=blue]
    > I am reading Herb Sutter's article:
    > http://www.cuj.com/documents/s=8840/cujexp0309sutter/
    > I have trouble to understand for following lines:
    >
    > class Subject {
    > // ...
    > public:
    > virtual void Attach( function<void (Subject*)> o ) {
    > obs_.push_back( o); } --Line1
    > virtual void Detach( function<void (Subject*)> o ) { /* ... */ }
    > virtual void Notify() {
    > for( list<function<v oid (Subject*)> >::iterator i = obs_.begin();
    > i != obs_.end(); ++i )
    > (*i)( this );
    > }
    > private:
    > list<function<v oid (Subject*)> > obs_;
    > };
    >
    > class ClockTimer : public Subject { // as before
    > // ...
    > void Tick() {
    > // ... timekeeping logic...
    > Notify(); // every so often, tick
    > }
    > };
    >
    > class DigitalClock : /*...*/ public Observer { // still works
    > // ...
    > public:
    > DigitalClock( ClockTimer* t ) : timer_(t)
    > { timer_->Attach( bind1st( mem_fun( &DigitalClock:: OnUpdateOf ),
    > this ) ); } --Line2
    > ~DigitalClock()
    > { timer_->Detach( bind1st( mem_fun( &DigitalClock:: OnUpdateOf ),
    > this ) ); }
    > void OnUpdateOf( Subject* timer ) { /* query timer and redraw */ }
    > private:
    > ClockTimer* timer_;
    > };
    >
    > Here are my questions:
    > 1. mem_fun() generates the unary functor, but bind1st() takes binary
    > function as its 1st argument, how does Line2 work?[/color]

    bind1st basically converts a two-argument member function (well,
    you have to know about the "hidden argument" to understand why I
    call a non-static member with one argument a two-argument function)
    into a functor that acts like a one-argument non-member function.
    IOW, a call

    this->OnUpdateOf(??? )

    gets converted into _someSpecialCas e_of_OnUpdateOf (???), where 'this'
    is the object stored in what 'bind1st' returns:

    void _result_of_appl ying_bind1st_(S ubject* t) {
    return stored_object_p ointer->OnUpdateOf(t );
    }
    [color=blue]
    > 2. Could you please provide stepwise explanation how Line2 being
    > expanded to fit member function signature of Attach(function <void
    > (Subject*)> )?[/color]

    Well, I don't know what 'function' is, so you'll have to excuse me
    if I won't satisfy your request. Why can't you do it?
    [color=blue]
    > 3. is "this" on Line2 a DigitalClock*?[/color]

    Yes.
    [color=blue]
    > DigitalClocl* is not Subject*
    > for Attach(), isn't?[/color]

    No, it's the hidden first (or, rather, zeroth) argument of that
    member function, passed to the OnUpdateOf by the functor returned
    from the call to 'bind1st'.

    'mem_fun' returns an object that uses its first argument as a pointer
    to the class.

    Take the <functional> header and look at the implementation. It will
    become clearer. If not, buy the Josuttis' book "The C++ Standard
    Library".

    Victor


    Comment

    Working...