Boost logo

Boost Users :

From: Edward Diener (eldiener_at_[hidden])
Date: 2008-05-06 14:26:57


Steven Watanabe wrote:
> AMDG
>
> Greetings from BoostCon,
>
> Edward Diener wrote:
>> template<class Seq>
>> struct biggest_float_as_double :
>> mpl::deref
>> <
>> typename mpl::max_element
>> <
>> typename mpl::replace
>> <
>> Seq,
>> float,
>> double
>> >::type,
>> mpl::less
>> <
>> mpl::sizeof_<_1>,
>> mpl::sizeof_<_2>
>> >
>> >::type
>> >
>> {};
>>
>> In two cases in the nested construct above one uses the 'typename
>> xxx<...>::type' construct whereas in one case one does not. There seems
>> to be some logic or rule about this but I do not understand what it is.
>>
>
> The ::type is no needed on the deref because we want biggest_float_as_double
> to inherit type nested ::type of deref. Thus,
> biggest_float_as_double<S>::type will
> be deref<...>::type. This technique is known as metafunction forwarding.

I understand the case of metafunction forwarding so I do understand why
the '::type' is not needed for mpl::deref. That is one of the few rules
I do understand which tells me that '::type' is not needed.

What I do not understand form the above is why '::type' is needed for
mpl::replace and mpl::max_element but it is not needed for mpl::less and
mpl::sizeof_. What is the difference in these constructs which require
'::type' for some and does not require '::type' for others ?

>
>> A few pages later in the text I see:
>>
>> typedef mpl::vector
>> <
>> mpl::vector_c<int, 1, 2, 3>,
>> mpl::vector_c<int, 4, 5, 6>,
>> mpl::vector_c<int, 7, 8, 9>
>> >
>> S;
>>
>> typedef mpl::transform
>> <
>> S,
>> mpl::front<_>,
>> mpl::inserter
>> <
>> mpl::int_<0>,
>> mpl::plus<_,_>
>> >
>> >
>> ::type sum;
>>
>> Here we have another nested mpl construct and I do understand the logic
>> of it, but here there are no internal nested '::type' statements. Once
>> again I am utterly puzzled about the whys and wherefores of using or not
>> using '::type'.
>>
>
> front<_> is an MPL lambda expression.

According to the book, metafunction classes and placeholder expressions
are MPL lambda expressions. Since front<_> is a placeholder expression I
understand that it is an MPL lambda expression. By the same definition
plus<_,_> is also an MPL lambda expression.

> It is not supposed to
> be evaluated immediately.

OK, I understand that placeholder expressions are not evaluated immediately.

What does evaluating an expression immediately have to do with appending
'::type' ?

> mpl::transform will evaluate it substituting
> each element of the sequence for _.

Yes, understood.

> leaving the ::type of plus<...>
> is a shortcut which works for numeric metafunctions.

So is the rule in this regard that numeric metafunctions can be passed
around without having to specify '::type' ? If so, what set of MPL
metafunctions constitute the numeric matfunctions ?

> There would
> be no problem with adding a ::type.
>
> mpl::inserter is an mpl object rather than an mpl metafunction.

So the rule here is that an mpl 'object' never needs a '::type' since it
is already a type ? If so, how do I tell which mpl constructs are mpl
'objects' ?

>
>> Finally I turn the page and I see this MPL construct:
>>
>> template<class Seq>
>> struct reverse :
>> mpl::fold
>> <
>> Seq,
>> typename mpl::clear<Seq>::type,
>> mpl::push_front<_,_>
>> >
>> {};
>>
>> Once again I can follow the logic and the explanation of mpl::fold, but
>> I have no idea by what rule one of the nested constructs has '::type'
>> appended and the next one does not.
>
> Again,
>
> mpl::push_front<_,_>
>
> is a lambda expression. Its evaluation is delayed.

See my question above about evaluating expressions.

Eddie


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net