Boost logo

Boost Users :

Subject: Re: [Boost-users] Why is cref required in this nested bind example?
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2012-12-06 18:07:03


> On Tue, Dec 4, 2012 at 4:48 PM, Nathan Crookston
> <nathan.crookston_at_[hidden]> wrote:
> >> //bind(b, bind(a));//*1
> >> bind(b, cref(bind(a)));//*2
> >
> > In short, *1 is evaluating a()
>
> Thank you. This surprises me as I thought boost::bind returned an
> object of type boost::function. I need to understand this better and
> am about to go read more on this.

The exact return type of boost::bind is unspecified. It's guaranteed
to be a function object that is callable with certain arguments, so
in that sense you can think of the return type as being *like* a
boost::function, but it doesn't have to actually be boost::function
(and in practice it won't be, because boost::function's ability to
wrap any callable object incurs a performance overhead, which is
not necessary for bind).

> > It would be more idiomatic to use protect:
> >
> > bind(b, boost::protect(bind(a)))
>
> I made the change, thank you. Hopefully when I understand better what
> boost::bind is doing (i.e. not returning a boost::function) it will be
> obvious why I need boost::protect. My guess is that boost::protect
> converts whatever boost::bind does return into a boost::function.

boost::protect itself just wraps the function object returned by bind()
into another function object, which is callable in the same way, but
is marked as being "protected". This marking is only meaningful when
the function object is used as an argument to another bind expression.
The outer bind expression recognizes the marking, and does a different
thing based on whether it's there or not:
  - If the marking is there, it treats the argument like any other
    function object (in your case, this is the behaviour you desire).
  - If the marking is not there, it composes the two function objects
    (see [1] for details). This is an extra feature of boost::bind that
    allows you to accomplish something that you couldn't otherwise.
    protect() is provided as a means to disable this feature in cases
    when you just want the regular behaviour (as in your case).

Hope that clears things up a bit.

Regards,
Nate

[1] http://www.boost.org/doc/libs/1_52_0/libs/bind/bind.html#nested_binds
                                               


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net