C ++ 11 Templates, Alias ​​for parameter package

In my personal project, I have something like this:

template <typename T>
class Base {
    //This class is abstract.
} ;

template <typename T>
class DerivedA : public Base<T> {
    //...
} ;

template <typename T>
class DerivedB : Base<T> {
    //...
} ;

class Entity : public DerivedA<int>, DerivedA<char>, DerivedB<float> {
    //this one inherits indirectly from Base<int>, Base<char> & Base<float>
};

A "base" class is a kind of adapter that allows me to see "Entity" as an int, a char, float, or whatever I want. DerivedA and DerivedB have different conversion methods. Then I have a class that allows me to store various representations of my object as follows:

template <typename... Args>
class BaseManager {
  public:
    void store(Args*... args){
        //... do things
    }
};

I have many different "Entity" classes that have different "base" collections. I want to be able to store a list of types in an alias like:

class EntityExtra : public DerivedA<int>, DerivedA<char>, DerivedB<float>{
  public:
    using desiredBases = Base<int>, Base<char>, Base<float>; /* here is the problem */
};

Therefore, I can use it as follows:

EntityExtra ee;
BaseManager<Base<int>, Base<char>, Base<float> > bm;  // <- I can use it this way
BaseManager<EntityExtra::desiredBases> bm;            // <- I want to use it this way
bm.store(&ee,&ee,&ee);  // The first ee will be converted to a Base<int>, the second to Base<char>  and so on

Is there a way to make an alias for an arbitrary type list and then use it in a template parameter package?

+4
1

, :

template <typename ...P> struct parameter_pack
{
    template <template <typename...> typename T> using apply = T<P...>;
};

// Example usage:

struct A {};
struct B {};
struct C {};

template <typename...> struct S {};

using my_pack = parameter_pack<A, B, C>;

my_pack::apply<S> var; // Equivalent to `S<A, B, C> var;`.

:

class EntityExtra : public DerivedA<int>, DerivedA<char>, DerivedB<float>{
  public:
    using desiredBases = parameter_pack<Base<int>, Base<char>, Base<float>>;
};

// ...

EntityExtra::desiredBases::apply<BaseManager> bm;
// Creates `BaseManager<Base<int>, Base<char>, Base<float>> bm;`.
+3

Source: https://habr.com/ru/post/1682149/


All Articles