Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2007-03-22 15:53:22


On 3/22/07, shunsuke <pstade.mb_at_[hidden]> wrote:
> Daniel Walker wrote:
> > Plus, as Eric pointed out earlier in this thread, the result_of
> > convention of using result<> for return types is now standard (is that
> > TR1?). Why shouldn't lambda follow it?
>
> As pointed, lambda should and can follow 'result_of'
> by using this way: http://tinyurl.com/2xw4s2
> , which will be <boost/lambda/result_of.hpp> or something.
> Note that the nullary instantiation seems not special case.

OK I think we're getting closer to a good solution.

Your file has specializations for lambda::lambda_functor that work for
lambda expressions, which is why the nullary instantiations work. My
result_of patch also had a specialization for lambda::lambda_functor,
which made the nullary case work.

If lambda expressions provided the standard result<> (as Eric
suggested and my lambda patch implements) only the specializations for
the nullary case would be necessary (unless this special case were
removed entirely from result_of using has_template_xxx).

I would be perfectly happy using your <boost/lambda/result_of.hpp> for
the nullary case alone, if we moved it to
<boost/lambda/detail/result_of.hpp> and had the boost/lambda/* headers
include it so that lambda/result_of interoperability was transparent
to the user. That combined with the lambda patch would probably
suffice.

However, this doesn't take care of the case where the user would like
to use a lambda compatible functor with result_of directly, as in
calling a functor right away rather than delaying the call with
lambda::bind per my previous example in this thread. It also doesn't
take care of your example of calling lambda::construct<> directly
without lambda::bind.

To handle lambda::construct<> and the other lambda wrapper functors
you could add nullary specialization of result_of to your file. We
should also have the wrapper classes expose result<> so that they are
more standard conformant. This will handle the nary result_of cases
for lambda wrapper functors.

To handle arbitrary user defined lambda compatible functors still
requires adding sig<> support to result_of (or a function adapter that
user's can use to convert their functors). Or we could just not handle
this case. Users currently can't use these functors with result_of
anyway. So, I suppose no one's feelings will be hurt if result_of
doesn't support their current lambda compatible functors. Besides,
when they upgrade to the result<> standard that lambda accepts with my
patch, they get result_of compatibility as a bonus. If we don't handle
user defined lambda compatible functors I see no need to patch
result_of at all, which I think would make everyone happy.

This is beginning to sound like a good approach to me.

>
> > The third case could be changed to be dependent on the number of
> > arguments (after giving the user a chance to supply result_type or
> > result<>) if that's preferable. This is simple to implement with
> > has_template_xxx. Am I missing something?
>
> As the rationale states, nullary intantiations of 'result_of'
> must always succeed even if the functions are never called.
> (Hence, it has the *default* result type -- 'void'.)
> Can has_template_xxx detect whether or not
> a sig-compatible functor is nullary-callable?

Yes. With my patch nullary instantiations of result_of are succeeding:
result_of<F()>::type is void. The problem as far as I can tell is that
result_of is choosing the default void rather than correctly deducing
the actual return type as given by F::result<F()>::type or
F::sig<tuple<F> >::type. But this has always been a limitation of
result_of. The way to get around it is by specializing result_of for
nullary F. I believe has_template_xxx could take away this limitation
by only choosing the default type void when the functor doesn't have
F::result<F()>.

>
> >> I guess a sig-compatible functor which is nullary-callable must be
> >> ported to result_of, even if the patch is applied.
> >
> > The same is true for a result-compatible functor as described above.
> > This is an existing limitation of result_of which we may or may not
> > want to address.
>
> If user workarounds of sig-compatible functor users cannot be removed,
> that patch loses the original intention?

I'm not sure if I fully understand your question, but the patch
doesn't lose the original intent entirely. Users can still use nary
sig-compatible functors, which they couldn't use before. (However, as
I stated above, it would be convenient but I'm not sure that it's
necessary for result_of to support the current sig convention.) Lambda
users are in the same boat as people writing result-compatible
functors when it comes to nullary calls. They need to write a
specialization of result_of for when their functor is called with no
arguments. result_of doesn't attempt to automatically deduce the type,
although it could with has_template_xxx.

>
> has_template_xxx seems not to work.
> I tried this:
>
> typedef char value_type;
> BOOST_MPL_ASSERT((
> has_template_result<
> pair_maker,
> pair_maker(value_type, value_type)
> >
> ));
>
> This assertion fails under VC7.1/VC8.

That's expected. Someone needs to cover the compiler workarounds that
has_xxx includes, and I'm not sure if I can do that right away. I may
give it a shot. Note that result_of still works on VC7.1 and VC8, but
the new functionality is not be available.

Daniel


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