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.

⚠️ **GitHub.com Fallback** ⚠️