|
Boost : |
From: Andrei Alexandrescu (andrewalex_at_[hidden])
Date: 2001-11-21 01:52:53
> Here's the definition of make_list:
> http://www.lambdasoft.dk/comet/doc/typelist_8h-source.html
>
> What's wrong with this approach? Is it failing on point #2?
It looks like you can call make_list with at most 40 arguments. It's true
that yo might never need more, and if you do, you can use append.
I don't know. I'd love to deprecate the TYPELIST_nn macros, but a truly
elegant solution would be the language to support variadic arguments in
templates. This feature, if also applicable to functions, would make a lot
of library code that people wrote (Loki::Functor, Loki::Variant, ScopeGuard
come to mind) really small and nice, and would render true our dreams of a
typesafe printf equivalent.
More concretely, I am thinking of something that allows the programmer to
progressively reduce a template's number of arguments through
specialization:
// Declare a class template that can take any number of parameters
template <typename[] Ts> class Widget;
// Specializations that kick in
// For one argument only
template <typename T>
class Widget
{
...
};
// For more than one argument
template <typename T, typename[] Ts>
class Widget : public Widget<T>, public Widget<Ts>
{
...
};
When you instantiate Widget<int, double, float>, first the second
specialization kicks in with int as T and (double, float) as Ts. Then,
Widget<int> is instantiated (first specialization kicks in) and
Widget<double, float> is instantiated, which in turn instantiates
Widget<double> and Widget<float>.
For functions, a possible syntax would be:
// Declare a safe vararg function
template <typename[] Ts> void Printf(const char*, Ts);
You cannot use the second argument directly if it is in the form typename[],
but you can "consume" the number of arguments one at a time through
overloads and/or specializations (this part is unclear to me):
// Declare a safe vararg function
template <typename[] Ts>
void Printf(const char*, int, Ts);
// Another one
template <typename[] Ts>
void Printf(const char*, double, Ts);
and so on. I guess such a facility, although not too rich, would be enough.
Well if you have the above, you can implement VERY easily and very
elegantly:
* Typelists (or would they be type vectors?)
* Tuples
* Functors
* Factories
* Visitors
* Variants
* Typesafe variadic utility fns such as
=> printf
=> min/max with multiple args, etc.
=> smart constructors "create a vector containing 1, 2, 3, 4, and 5"
* many others
Andrei
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk