Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-11-23 09:56:29


From: "Aleksey Gurtovoy" <alexy_at_[hidden]>
> > What particular differences do you have in mind?
>
> Well, you've clarified some of the issues below, but basically after the
> statement that "boost::mem_fn is a generalization of the standard
functions
> std::mem_fun and std::mem_fun_ref", I would like to see a disclaimer that
> still boost::mem_fn is not a complete replacement of those std components,

Yes, I see your point, but the documentation doesn't claim that mem_fn
replaces the standard functions. My initial goal was, indeed, to match them
as close as possible (hence the argument_type typedefs) but later I decided
that it's not possible (or necessary) to attempt 90+% compatibility.

That's why the argument_type typedefs aren't a part of the formal
specification. I've left them in 'cause they can't really hurt.

boost::mem_fn is simply not intended to be composed or bound by something
that needs typedefs.

> because there are cases when it has no choice but to lie in it
> '[first_]argument_type' typedef,

"conceal part of the truth". ;-)

> and in these cases you might have to resort
> to the what the standard library has to offer. For example, this doesn't
> compile:
>
> int print(std::string const&);
>
> struct my
> {
> std::string name() const;
> };
>
> boost::compose_f_gx(
> std::ptr_fun(print)
> , boost::mem_fn(&my::name)
> )(my()); // cannot convert parameter 1 from 'my' to 'my const*'
>
> and this does:
>
> boost::compose_f_gx(
> std::ptr_fun(print)
> , std::mem_fun(&my::name)
> )(my());

Did you mean std::mem_fun_ref?

> Which is not a big issue (you may even argue that one should use
boost::bind
> instead of boost::compose_f_[...] here and everywhere :).

Yes, this is what I'd argue. boost::mem_fn does two things: first, allows
you to write

std::for_each(v.begin(), v.end(), boost::mem_fn(&Shape::draw));

for a container of mem_fn-aware objects, and second, provides a component
(along with documentation) that may be reused whenever you (meaning a
library author) need transparently to treat a pointer to member function as
a function object. For example, it allows you to define (and easily document
'by reference') a for_each such that

for_each(v.begin(), v.end(), &Shape::draw);

is equivalent to the above.

Binding/composition support is left to boost::bind.

> But see, you
> cannot just say to your team "listen, boost::mem_fn is more general, and
it
> also works with both smart pointers and references, so instead of writing
> boost::mem_fun[_ref] in one place, std::mem_fun[_ref] in another, and yet
> boost::mem_fn in third one, let's just consistently use boost::mem_fn
> everywhere" - because it just won't work this way (at least not until the
> day you get rid of all these binders, composers, etc.). So it would be
nice
> if the library documentation acknowledged that fact (so one doesn't have
to
> re-discover it herself).

OK, I'll think about it. ;-)

--
Peter Dimov
Multi Media Ltd.

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