I am making another effort to understand MPL. I have the book by David Abrahams and Aleksey Gurtovoy, "C++ Template Programming", which is my basic source for learning the library, and I have the Boost documentation for the MPL. After reading chapter 3 again I think I understand the basic concepts more easily. However I am still missing something basic, which I think can be given the name: "How do I understand when to append and when not to append the '::type' to a metaprogramming construct built with MPL". Let me first say that I fully understand that '::type' is the way that the MPL returns compile time data in its metafunctions. Also that I understand that '::type' may refer to compile time numeric data ( including bool ) in the eventual form of '::type::value' and that '::value' is often supplied as a shorthand for compile time numeric data. Finally I do understand that to pass metafunctions around when a type is needed the MPL uses a metafunction class, which is a type and not a template. What I am missing is how to determine when using MPL functionality, whether it be data types, sequences, iterators, algorithms, or views being manipulated, when to append '::type' to the end of the intermediary expression or not. Let me give some examples of my confusion based on my reading in the MPL book listed above. I am reading about algorithms and I see an example whose logic I perfectly understand, and whose syntax goes like this: 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.
A few pages later in the text I see:
typedef mpl::vector
<
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'. 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. As a naive learner of the MPL I would have thought it would have been much easier to use if every MPL construct ( mpl::xxx... ) returned a '::type', and then this business of when to use and when not to use '::type' would have been regularized, but evidently MPL does not work that way. Since I still do not understand the rule about this, hopefully someone who knows MPL, and who realizes that while I understand the basic concepts I am still trying to understand it, can enlighten me on this subject.