|
Boost Users : |
From: Edward Diener (eldiener_at_[hidden])
Date: 2008-05-06 13:25:42
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<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'.
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.
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