Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2001-08-20 07:30:34


From: "Mark Rodgers" <mark.rodgers_at_[hidden]>

> > * Optionally, I can make mem_fun rename-able (via #define BOOST_MEM_FUN
> > something) for users that insist on using everything at once, although I
> > don't think that would be necessary.

On second thought all these suggestions are hacks that sweep the problem
under the carpet rather than solving it.

I'm now convinced that your original idea - having functional.hpp include
mem_fun.hpp - is the best solution.

I'll try to address your concerns raised in previous posts.

* Compiler compatibility:

mem_fun.hpp has been tested with VC 6, VC 7, Intel 5.0, g++ 2.95.3, bcc
5.5.1. Jens Maurer reported success with como and g++ 3.0 as well. In the
rare cases where functional.hpp does compile but mem_fun.hpp does not, we
can revert to the original definitions.

* Compile times:

I ran some informal tests. VC 6 compile times for function_test.cpp were
5.804s without mem_fun.hpp and 5.911s with it (five runs average, warm
cache.) bcc32 5.5.1 times are 4.783s and 4.788s respectively.

* Double copy:

I have considered the double copy problem when designing mem_fun and decided
to not try to 'fix' it. The arguments boil down to "trust the programmer"
but here's a more elaborate rationale:

- the 'double copy problem' - in the mem_fun case - is often an illusion.
The double copy never shows up in a profiler in my (admittedly limited)
experience since mem_fun mirrors the signature of the member function and
the class designer rarely chooses pass by value for types where the copy
constructor is expensive.

- using a heuristic to determine whether to pass by value or by const
reference is somewhat dangerous. Passing a double by value on compilers that
use registers or the FPU stack is much more efficient than by-ref that
forces a memory store. The converse is also true; for a small but
noncopyable class pass-by-value is not an 'efficient' way since it does not
compile.

- and finally we have the unfortunate precedent of std::auto_ptr where pass
by value has radically different semantics than pass by const reference:

#include <memory>
#include <boost/functional.hpp>

struct X
{
 void f(std::auto_ptr<int>);
};

int main()
{
 X x;
 std::auto_ptr<int> p(new int);
 boost::mem_fun(&X::f)(&x, p); // fail
}

For these reasons I decided to simply trust the judgement of the class
designer and not try to "guess."

> Or you could just rename it anyway so there is no conflict and we don't
> have to worry. Jens suggested member_fun.

Yes, I can rename mem_fun to mem_fn (I even like the name better) - a rather
obvious and easy solution - but this is not my goal. I want to position
mem_fun as a replacement for std::mem_fun (in the next standard.) [And
having it replace boost::mem_fun first will be a good test run.]

The committee then has the options of

* accepting mem_fun as is;
* accepting mem_fun but requiring that it returns objects of type named
(const_)mem_fun(1)_t in the zero/one arg cases;
* accepting it under a new name - mem_fn;
* rejecting it (of course.) :-)

Hopefully it (and bind) can even be used to demonstrate to the core group
that C++ needs a mechanism for dealing with arbitrary argument lists and a
solution to the forwarding problem.

> > Isn't it ironic that my earlier expression.hpp library used 'apply'
> > instead of 'bind' for this operation? Now I'm convinced that 'bind' is a
> > better name overall (all uses taken into account.)
>
> I think you got it right first time.

I'd like to think that I'm that good. Unfortunately I can't agree.

class button
{
public:
  boost::function<void> onClick;
};

class cd_player
{
public:
  void play();
};

playButton.onClick = bind(&cd_player::play, &cdPlayer);

A very common pattern. Also:

boost::thread t(bind(my_thread_proc, id, ref(data)));

And of course we have bind1st and bind2nd which bind replaces.

You can't accuse me of being biased. After all, 'apply' was my first choice.
:-)

I can understand people that don't like 'bind' and '_1' at first glance,
because I've been down the same road, and at first used the very same
alternative spellings that have been proposed - 'apply' and 'arg1'. I can
confidently predict, however, that when the dust settles, many of you will
find the names quite natural.

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