Preparing types for usage with template Typepack - GerdHirsch/GenericTools GitHub Wiki
##An Idiom
To enable the seamlessly use of
Typepack<..>
for a specific varidic template,
the usage of the template can be encapsulated with an interface
which calls a type-function that converts Typelist<..>
into a <class ...pack>
and delivers the
created type.
The interface should be named like the original template was named: Widget
, the type-function that creates
the type should be named CreateWidget<..>
and the implementation should be named WidgetImpl
,
with Widget as the name of your abstraction.
// the implementation of the abstraction
template<class ...pack>
class WidgetImpl{ /* definition */};
// type-function to create the implementation
// primary
template<class ...pack>
struct CreateWidget{
using type = WidgetImpl<pack...>;
};
// specialization for Typepack<pack...>
template<class ...pack> // delegation by inheritance
struct CreateWidget<Typepack<pack...>> : CreateWidget<pack...>{};
// interface for the abstraction
template<class ...pack>
using Widget = typename CreateWidget<pack...>::type;
// usage:
using pack = Typepack<A, B, C>;
Widget<pack> w1;
Widget<A, B, C> w2(w1);
Widget<pack> w11(w2);
w11 = w1;
w2 = w11;
w1 = w2;
Note: Widget <..>
is not specialized for Typepack<..>
but can be used with it!
The outcome of the call Widget<pack>
above is a parameter pack with one argument: pack
of type Typepack<A, B, C>
and this is delegated to CreateWidget<..>
which is specialized for that kind of type.
Because CreateWidget<..>
is a type-function, the created type is always a WidgetImpl<..>
no matter whether
the argument was a parameter class ...pack
or a Typepack<..>
.
The specialization of CreateWidget<Typepack<pack...>>
inherits the member type
definition using type =
from its baseclass, the primary template CreateWidget
,
which means it delegates the creation of WidgetImpl
to its baseclass.
With a specialization of the original template like Widget
in
Storing parameter packs
for Typepack<..>
the types created with Widget<A, B, C>
and Widget<pack>
are incompatible.
In Demo is a complete example.