Boost logo

Boost :

From: Ross Smith (ross.s_at_[hidden])
Date: 2001-08-16 16:19:51


Peter Dimov wrote:
>
> From: "Ross Smith" <ross.s_at_[hidden]>
>
> > Under "Using bind with member function pointers", I don't understand one
> > of the examples:
> >
> > > bind(&X::f, &x, _1)(i); // (&x)->f(i)
> >
> > Is this meant to imply that a pointer passed where the object is
> > expected will automatically be dereferenced when the function is called?
>
> No, bind does not dereference pointers. The reason this works is that
>
> bind(&X::f, &x, _1)
>
> is actually a shortcut form for
>
> bind<R>(mem_fun(&X::f), &x, _1)
>
> and it's the function object returned from mem_fun that is able to handle a
> pointer or a reference to X as a first argument.

The documentation doesn't mention mem_fun, so the reader has no way of
guessing what's going on here short of delving into the implementation.

The full set of examples are:

> struct X
> {
> bool f(int a);
> };
> X x;
> shared_ptr<X> p(new X);
> int i = 5;
> bind(&X::f, ref(x), _1)(i); // x.f(i)
> bind(&X::f, &x, _1)(i); // (&x)->f(i)
> bind(&X::f, x, _1)(i);
> bind(&X::f, p, _1)(i);

It certainly looks as though there's something there -- whether it's
bind itself or the hidden mem_fun -- that happily accepts either a
pointer or the actual object. I'm not familiar with mem_fun, and the
relevant section of the standard is a bit on the cryptic side; does it
accept both? If not, what's going on here?

In any case, I repeat my suggestion that this needs more documentation.

> The "perfect" syntax for a bound function is:
>
> f($2, $1)
>
> or
>
> f(%2, %1)
>
> depending on what skool you're from. [Likewise $1 + $2 for lambda(x, y)(x +
> y).]

I'm from the "clear names are more important than traditional ones"
school.

> In my experience, the _1 notation really stands out and is not easily
> confused with either 1 or -1.

I disagree. Very strongly. Very, very, _very_ strongly.

> In contrast,
>
> bind(f, arg2, arg1)
>
> is less readable for someone that's not "in the know" - arg1 and arg2 are
> pretty ordinary identifiers; the person will lose several minutes looking
> for the variables named argN.

Not if they're properly qualified (boost::arg1). (I'm also from the
"using namespace foo should be a hanging offence" school of thought.)

> > likely to have used as a macro somewhere deep in the bowels of
> > <windows.h> or <unistd.h>. Please, _please_ do something about this.
>
> I'm willing to take the risk. Nobody is safe from macros (pascal, min,
> Sleep.) Of course if someone does report a conflict, _bi will change.

Couldn't you at least make the trivial change to trailing underscores
instead of leading ones? It doesn't make the names any longer, and it
avoids all the implementation namespace problems.

-- 
Ross Smith <ross.s_at_[hidden]> The Internet Group, Auckland, New Zealand
========================================================================
"Unix has always lurked provocatively in the background of the operating
system wars, like the Russian Army."                  -- Neal Stephenson

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk