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
, mpl::vector_c , mpl::vector_c 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