|
Boost : |
From: David Abrahams (dave_at_[hidden])
Date: 2003-01-07 10:03:19
"Yitzhak Sapir" <yitzhaks_at_[hidden]> writes:
> 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."
Yeah, it doesn't do very well in that department.
> 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 <<.
Dave's mention of efficiency was the weakest part of the argument, but
significant nonetheless.
> 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.
Yep. I'm nervous about showing iteration and sequences in a this
example, though. There's nothing that sophisticated going on in
"hello, world."
> 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:
...
Sure, it's comparitively easy to come up with useful examples that are
more complicated. Incidentally, yours needs some tweaks for
generality. The main reason is that for_each tries to
value-initialize an instance of each of the types it processes and
passes that to the function object. If the type isn't
default-constructible, it won't compile. I'm not sure that preserving
this property is worthwhile. Opinions, Aleksey?
typedef list<
pair<int_c<0>, int>
, pair<int_c<1>, double>
, pair<int_c<2>, string>
> typelist;
int discriminator;
stream >> discriminator;
variant<transform<typelist,select2nd>::type> v;
for_each<typelist, wrap>(serialize_if_appropriate(discriminator, stream, v));
^^^^
with the following definition:
struct serialize_if_appropriate
{
public:
...
template <class W>
void operator()(W&) const
{
typedef W::type T; // <--
if (T::first::value == discriminator) {
T::second::type t;
stream >> t;
v = t;
}
}
private:
istream& stream;
int discriminator;
variant<typelist> v;
};
-- David Abrahams dave_at_[hidden] * http://www.boost-consulting.com Boost support, enhancements, training, and commercial distribution
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk