Boost logo

Boost :

From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2008-05-13 10:01:42

On Tue, May 13, 2008 at 3:11 PM, Marco Costalba <mcostalba_at_[hidden]> wrote:
> On Mon, May 12, 2008 at 7:39 PM, Giovanni Piero Deretta
> <gpderetta_at_[hidden]> wrote:
> >
> > I.e. MSF is the natural extension of boost::function in the realm of
> > polymorphic function objects (well, you still
> > have to choose beforehand the types you want to work with, but it is
> > still much better than boost::function).
> >
> > [ BTW, by a quick at the code of MSF you do not seem
> > to implement the result_of protocol. You definitely should, as MSF is
> > definitely a polymorphic function object,]
> IOW you mean that given
> typedef boost::msf_function<double(double),
> int(int),std::string(std::string)> MSF;
> The implementation should lead to...
> boost::result_of<MSF(double)>::type i; // i is a double
> boost::result_of<MSF(int)>::type i; // i is an int
> boost::result_of<MSF(std::string)>::type i; // i is a std::string
> Is this correct?

Exactly! MSF should support it.

> >
> > Still your current implementation has a problem.
> >
> --strip----
> > msf_function<int(int), double(double), my_big_int(my_big_int)> x = frob(10);
> >
> > it has two downsides ...
> > 1) it does N dynamic allocations, one for each signature.
> well, a boost::function is allocated (empty) on the stack because it's
> a member data.

boost::function in most cases does an internal allocation. If I follow
the implementation
correctly (which of course might not be:) ) , I think that MSF
contains a boost::function for every possible signature. For funciton
pointers this shouldn't be a problem because boost::function is
optimized for small objects, but for more
consistent functors it might require a fair number of allocations.

> > 2) it has N copies of 'frob::state', which for a small object as an
> > int it is not a problem, but in principle it can be wasteful
> >
> > ... and a serious problem:
> > As there are n different states, the increment is separate for each
> > type, and not for all of them:
> >
> This is more a "behaviour" then a problem,

It is a problem only if one expects that behavior. The current
implementation isn't
 necessarily wrong, but I think that is surprising, since MSF wants to
be an obvious extension
to boost::function.

> as example I can have a
> state named calls_counter that counts how many time an operator() has
> been called for each different type of arguments. In this case having
> separate state is a need:
> T operator()(T i) {
> calls_counter++;
> something....
> return some_value;
> }

My point is that you get the separate objects behavior from the same
object behaviour
at no extra cost, while the reverse is impossible. This is why I think
that the 'same object' behavior is
more fundamental (and IMHO the expected) and it is what MSF should implement.

> The real problem IMHO is that this behaviour is not well documented,
> I'll fix this.
> > In practice MSF acts as N different boost::function objects with a
> > think type based dispatcher.
> > I can of course fix the problem by adding another layer of indirection:
> >
> Have you tried to fix it with
> msf_function<int(int), double(double), my_big_int(my_big_int)> x;
> x = boost::ref( frob(10) );
> Indeed boost::function supports ref() and cref() to avoid the copy
> when is not needed or when the copy is simply wrong. MSF supports
> ref() and cref() too and forwards them, still wrapped, to the
> underlying boost::function objects so that no copy of the wrapped
> polymorphic function object is made.

This has different semantics from what I wanted. I do not want to have
to keep the wrapped object in the stack to add it in a wrapper.
In this case I need I want MSF to copy my object (i.e. to manage its
lifetime) but I want it to do only one copy (usually for efficiency,
but sometimes like this case, for correctness).

> Thanks

Thanks to you. I think that MSF might be a valid addition to boost.


Boost list run by bdawes at, gregod at, cpdaniel at, john at