2015-05-30 13:26 GMT-03:00 Peter Dimov <lists@pdimov.com>:
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<add_reference<add_const<add_pointer<_1>>>, X>::type; and even if that single typename <>::type is found too much to bear, one has now the option to adopt the C++14 convention and define apply_t accordingly. The most important thing to realize here, however, is the fact one retains the option to lazily eval the expression if so desired, or rather required in a SFINAE context. That is to say, typename <>::type must be regarded as a feature, not as an awkward implementation detail. I urge you to refrain from using C++11 so promptly as an excuse to deem MPL obsolete. It has been the de facto metaprogramming library for over a decade now for a good reason and, in my opinion, C++11 is not changing that any time soon. Sure there are now other very elegant alternatives, Hana and many others are there to prove it, but I don't see why deprecating a library whose simplicity has allowed support of a remarkable number of compilers still in production use today, many of which can't cope with the newest C++14 constructions yet. *Bruno C. O. Dutra*