Boost logo

Boost :

From: Brian McNamara (lorgon_at_[hidden])
Date: 2003-10-10 03:07:28


> Douglas Gregor <gregod_at_[hidden]> writes:
> > At the risk of being too cute, perhaps result_of<F> could be the name for
> > metafunction_result_type_computer<F>. Then we have:
> >
> > result_of<F(T1, T2, ..., TN)>::type returns the type of f(t1, t2, ..., tN)
> > given an object f of type F and objects t1, t2, ..., tN of
> > types T1, T2, ..., TN respectively
> >
> > result_of<F>::apply<T1, T2, ..., TN>::type ==
> > result_of<F(T1,T2,...,TN)>::type

Douglas: does the fact that result_of is (or will be in some TR?) a "std"
entity hinder this? Or were you imagining defining boost::result_of,
which would do what std::result_of does, plus more?

On Thu, Oct 09, 2003 at 10:05:38PM -0400, David Abrahams wrote:
> Makes me wonder if we want that or
>
> result_of<F>::apply<type_sequence>::type
>
> e.g.
>
> result_of<F>::apply<mpl::vector<T,U,V> >::type
>
> It may depend on which is a more likely use-case.

I think the former, since in the non-meta case (actual function calls),
it is hard to generalize the notion of N arguments. But...

> OTOH I'm sure it's simple to build an MPL facility that transforms one
> into the other; we may have it already; seems too useful not to have.

Yeah. I think any potential interface mismatches here can be massaged
away without too much trouble.

I want to return to one of David's (pre-"most of this discussion")
use-cases:

> Say you're building a tuple transform iterator. You have a functoid
> and an mpl::list of the underlying sequence value_types, and you want
> to compute the return types of the dereference operator.
>
> typedef mpl::transform<
> inner_value_types
> , functoid
> >::type outer_value_types;
>
> The fact that it took me all of 5 seconds to come up with this
> example tells me there are lots of others ;-)

So, lemme write another use case along these lines.

Suppose we have a tuple of inner_value_types (T,U,V...) and we want to
transform it into a tuple of outer_value_types (T*,U*,V*,...) because we
intend to iterate over the data in the tuple with the functoid (or
"UnaryResultOfCallable" object) "heapify":

   heapify( T x ) means { return new T(x); } // make a copy on the heap

Then, assuming all the things we've been discussing, I think that the
MPL code ends up looking like

   typedef mpl::transform<
       inner_value_types
     , result_of<heapify_type>
>::type outer_value_types;

Is this good? It is certainly not bad, but in the role of "take a
functoid and turn it into a metafunction", I am not sure that
"result_of" is the best name. That is, I think it might "read" better
as

   typedef mpl::transform<
       inner_value_types
     , as_result_type_metafunction<heapify_type> // note difference
>::type outer_value_types;

or something. Again, I cannot think of a terse name which effectively
communicates "take a functoid and turn it into a metafunction". But I
don't think that "result_of" is the best name for this.

-- 
-Brian McNamara (lorgon_at_[hidden])

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