2015-05-30 13:26 GMT-03:00 Peter Dimov
I've recently made the mistake to reread Eric Niebler's excellent "Tiny Metaprogramming Library" article
http://ericniebler.com/2014/11/13/tiny-metaprogramming-library/
which of course prompted me to try to experiment with my own tiny metaprogramming library and to see how I'd go about implementing tuple_cat (a challenge Eric gives.)
Ordinarily, any such experiments of mine leave no trace once I abandon them and move on, but this time I decided to at least write an article about the result, so here it is, with the hope someone might find it useful. :-)
Very didactic overview on C++11 metaprogramming, I find many of your points
of view very much aligned to my own. I do believe however some of your
assumptions are a bit to hasty.
Higher order constructs, such as argument binding, are necessary in order
to enable a truly expressive functional idiom and template aliases can't
possibly make for a reasonable substitute for them. The need for so called
metafunction-classes arises most naturally as soon as one decides to write
a metafunction that returns another metafunction. As pointed out by
Vincente Escriba, template aliases can't allow for an indistinguishable
handling of metafunctions and variables (that is types), for the obvious
reason they can't match template type parameters.
Another thing that I believe has been overlooked, is the fact that the
property of lazy evaluation is entirely lost by directly typedef'ing
metafunctions as their result and, along with it, goes SFINAE friendliness
as well, or at least it becomes much trickier to pull. The ability to use
SFINAE as a means to select between alternative implementations is, I dare
say, the main reason why one decides to go all the way through
metaprogramming to begin with.
While I'm at it, I see that there's a widespread rejection to MPL's
typename <...>::type idiom but I fail to grasp the reason why. Sure one
might find it cumbersome to write it over and over again, but that's a
solved problem and has always been. MPL provides lambda<> and the
accompanying apply<> which elegantly overcome this cumbersomeness by
greatly reducing the necessity to sprinkle typename <...>::type all over
the place.
Taken from your article
typedef
typename add_reference<
typename add_const<
typename add_pointer<X>::type
>::type
>::type Xpcr;
becomes simply
using Xpcr = typename apply