Boost logo

Boost :

From: Yitzhak Sapir (yitzhaks_at_[hidden])
Date: 2003-01-07 08:59:58


> -----Original Message-----
> From: David B. Held [mailto:dheld_at_[hidden]]
> Sent: Monday, January 06, 2003 8:14 PM
> To: boost_at_[hidden]
> Subject: [boost] Re: Hello MPL world!
>
> While this is a cute idea, my first impression would be: "Uh...is this
> really something I could use in my own code?" On the other hand,
> I seem to use compile-time if more than anything else, even in "user
> code". I suspect that most people will use mpl::if_ and type traits
> more than anything else, so I think Dave's original example with
> is_pointer<> would connect with the most programmers. On the
> other hand, I suspect that library authors are more likely to use the
> type containers and algorithms, so an example illustrating those might
> be more appropriate for them. So I guess it depends on the
> intended audience.

> P.S. Outputting "Hello, world" in a way that generates significantly
> more code than the run-time version is probably not a good way to
> endear users to metaprogramming. ;>

The original version I suggested used fold, and for that, you do need to
use if_ since you need to determine whether to call Prev::eval(). I didn't
post my implementation since it took me quite a while to get it working
with VC6.5 and I thought only the general concepts were necessary,
not a full blown example. In any case, I think just using if_ and type
traits lacks the "small rush of excitement when you see it work."

Regarding the "much more code," metaprogramming is used to
produce a lot of inline code in Blitz style templates. This is considered
a type of optimization, mainly in speed. If there weren't a cout.write,
I think my example would work faster than the equivalent of using
streaming operators <<.

As for usefulness, I agree that the next thought after the rush of
excitement, is "so what?" I could argue that doing for_each on the
vector_c is not different than doing for_each on a compile time
vector of types. In fact, the functor receives a type, not a character.
Generation of long sequences of code is one use of
metaprogramming. A vector of pairs, might be used to implement
read serialization of a discriminated union. This is much more
useful, whether for a library author or not, but much more complex
for a beginning example to understand:

list< pair<int_c<0>, int>, pair<int_c<1>, double>, pair<int_c<2>, string> >

int discriminator;
stream >> discriminator;
variant<transform<typelist,select2nd>::type> v;
for_each<typelist, identity>(serialize_if_appropriate(discriminator, stream, v));

with the following definition:

struct serialize_if_appropriate
{
public:
   ...
   template <class T>
   void operator()(T&) const
   {
      if (T::first::value == discriminator) {
          T::second::type t;
          stream >> t;
          v = t;
      }
   }

private:
   istream& stream;
   int discriminator;
   variant<typelist> v;
};


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