Boost logo

Boost :

From: Giovanni Piero Deretta (gpderetta_at_[hidden])
Date: 2008-05-10 12:08:22


On Sat, May 10, 2008 at 11:36 AM, Marco Costalba <mcostalba_at_[hidden]> wrote:
> On Sat, May 10, 2008 at 10:43 AM, vicente.botet
> <vicente.botet_at_[hidden]> wrote:
> >
> > Try with
> > struct foo_t { template<class T> void operator()(T){} } foo;
> >

Yep, sorry for the typo :)

>
> boost::function<void(int)> f = foo; // ok it works, no ambiguity,
> object is instantiated as foo_t::operator<int>()
>
> boost::multi_signature_function::
> function<boost::mpl::vector<void(int), void(std::string)> > msf = foo;
>
> // error! Ambiguous call <strip> could be void(int) or <strip>
> void(std::string)
>
>
> msf = f; // this works! no more ambiguity, foo_t is instantiated with T = int
>
>
> So the bottom line is that it does not work because compiler does not
> know to which internal boost::function to bound foo, because it could
> be bounded to both boost::function<void(int)> and
> boost::function<void(std::string)> an "ambiguous call" type error
> arise...as it should, if I can dare.
>

Well my idea was that an unconstrained template function object would be
bound to all internal boost::functions (in fact this would require MSF to hold N
 instances of the function objects, in an ideal case it would only
hold one instance
and have a function pointer per every signature).

In fact in this case using operator= makes sense: you use it only one and all
signatures are applied to the object in the RHS. I think that in your
case, using
operator= is confusing because you are not really reassigning the MSF but
just adding an overload. What if operator= tries to bind all signatures at
once (and thus allows for boost::function like adaptability) and operator+=
(or an explicit add member function) is strict and allows to replace a single
overload?

This might not be what MSF is for, but I was thinking, for example,
of something like this:

struct visitor { template<class T, class State> void operator(State, T) {
   /* do something generically using State and T*/ } };

typedef boost::fusion::tuple<int, std::string, double, char> my_seq;

void for_each(my_seq&, msf<int, std::string, double, char>);
// for_each can now be implemented in another translation unit

// and used like this:
my_seq f;
struct my_state {...} state;

// note that with the current implementation we would have N copies
// state
for_each(f, boost::bind<void>(visitor(), _1, state));

>
> Replying to a previous message...
>
>
> >> This library extension, although flexible and IMHO powerful is notably
> >> very simple and small, so I would like to ask if someone is interested
> >> to add this code in some way directly to boost.function
> >>
> >
> >While useful, I do not think this library belongs in boost function (which is monomorphic),
> > but it should be a library of its own.
>
> Form boost.function documentation:
>
> "Generally, any place in which a function pointer would be used to
> defer a call or make a callback, Boost.Function can be used instead"
>
> Where boost.function naturally models a function, multi-signature
> boost::function naturally models an overload set

Actually it is a bit more, because you can have different state for
each overload. I would need something in the middle:
a single polymorphic closure which can be accessed dynamically
with multiple objects.

I can of course do this with your MSF by adding another
level of indirection, but it seems wasteful. it would be better
if it was the reverse (you have to pay for the storage of each signature
state only if you need it), IMHO it would be better.

-- 
gpd

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