Boost logo

Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-08-17 09:24:42


On Thursday 16 August 2001 07:35, you wrote:
> Douglas Gregor wrote:
> > Boost.Function can eliminate the need for the template parameters:
> > typedef boost::function<void> Action;
> > typedef boost::function<bool> Pred;
> >
> > A library like Lambda, Boost.Bind, or FACT would let you define the
> > predicate and action inline.
>
> In general, it cannot be done.
> If you consider, say:
>
> x = x + 1
>
> you can wrap it using something like
>
> ASSIGN ( VAR(&x), SUM ( VAR(&x), VAL (1) )
>
> [the actual tempate code is probably grosser :-[

I believe it would be:
  bind(ref(x) = ref(x) + free1, 1)

> but such a decomposition only works for some constructions.
> Other constructions cannot be wrapped. For example,
> functions with n arguments, where n exceeds the number
> supported by the library. Struct member access,
> pointer to member formation, exception handling,
> multiple inheritance ... the list is long.

Most of these are possible - "n" can always be increased (and most libraries
make it easy), Lambda supports exception handling; struct member
access/pointer to member formation can be done (just form a pointer-to-member
and pass it). I'm not saying the result is pretty, but I believe most
constructs _can_ be handled. The only glaring omission I've found is the lack
of "break"; exception handling works, but has terrifying performance
implications on some compilers :(.

Multiple inheritance doesn't quite fit the above list, unless we're talking
about very different problems...

[snip]
> FYI: I was writing a book on STL some years ago,
> and I gave up because, while it is _possible_ to do quite
> significant work using templates, the result
> is so gross as to be useless. You can replace
> a loop
>
> for(;;) { body }
>
> with
>
> for_each(body_functoid)
>
> but then you have to translate the body, and in the end
> the first form is easier to write, gives better
> diagnostics, compiles faster, generates better code,
> etc etc .. in the end, template metaprogramming
> is only interesting if you're considering how to
> fix the core language to actually make it useful.
>
> The killer was a triple loop: three or four lines
> of C++ turned into several _pages_ of templates.
> I used only plain STL, so I guess you could do better
> with more combinators (eg using Lambda or Bind,
> or whatever), but in the end, these library cannot
> solve the general problem, only slightly expand
> the class of problems which can be solved.

An identifier is worth a hundred comments, IMHO. This is by far more of a
religious issue than any other, but given:

Container container;
for(Container::iterator i = container.begin(), i != container.end(); ++i)
{
  // code that does something
}

vs.

for_each(container.begin(), container.end(), doSomething());

I'll almost always take the second version, because doSomething can be an
identifier that concisely state what operation is performed on each object.
It couldn't possibly read more clearly.

        Doug


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