Boost logo

Boost :

Subject: Re: [boost] "Simple C++11 metaprogramming"
From: Bruno Dutra (brunocodutra_at_[hidden])
Date: 2015-06-01 19:22:00


2015-05-30 13:26 GMT-03:00 Peter Dimov <lists_at_[hidden]>:

> 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. :-)
>
> http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html
>

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*


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk