Before I describe the problem I will give you an idea what is the target of my work.
I want to have a template which creates a class ( while do this unrolling a typelist recursively) which derives from all given types in a variadic list of parameters. That works fine. (see below)
Now is my target to provide all parameters to all constructors of the subclasses via an "automatic" created type from the unrolling template. Finally each of the Unroll classes should eat the parameters it needs to create a instance of the given classes. Each of the recursively created template instances should eat one of the parameter packs contained in the TypeContainer.
Before you ask: This code is only academic to learn new features of c++11. :-)
// create a wrapper around tuple to make it constructible with initializer list
template <typename ... T>
class TypeContainer: std::tuple<T...>
{
public:
TypeContainer(T... args):std::tuple<T...>(args...){};
};
// create a template to concatenate some typelists
// ??? is there a already usable template in std:: ???
template < typename ... X >
class TypeConcatenate;
template <typename T, typename ... S >
class TypeConcatenate < T, TypeContainer< S... >>
{
public:
typedef TypeContainer< T, S...> type;
};
// The follwing template unrolls a typelist and creates a recursively
// inherited class.
template <typename ... T> class Unroll;
template < class Base, class Head, class ... Next >
class Unroll< Base, Head, Next...>: public Unroll < Base, Next...>
{
public:
// collect all needed types for the instance creation of all child
// classes.
typedef typename TypeConcatenate<typename Head::Parms, typename Unroll < Base, Next...>::AllParms>::type AllParms;
};
template < class Base, class Head>
class Unroll < Base, Head>
{
// provide first parameter set for the constructor
public:
typedef TypeContainer<typename Head::Parms> AllParms;
};
template < class Base, class ... Next>
class Top : public Unroll < Base, Next...>
{
// I want to have a constructor which accepts
// all parameters for all the sub classes.
public:
template <typename ...T> Top(T... args);
};
// ??? The following lines of code will not compile!!!
// gcc 4.8.1 gives:
// error: ISO C++ forbids declaration of 'Top' with no type
// ??? Why the compiler could not interpret this as constructor ???
template <typename Base, typename ... Next, typename ... T>
Top<Base, Next...>::Top< TypeContainer<T...>>( T... args) {}
class Base {};
class A: public Base
{
public:
typedef TypeContainer<int, float> Parms;
A( int i, float f){}
} ;
class B: public Base
{
public:
typedef TypeContainer< char, int> Parms;
B( char c, int i){}
};
Top<Base, A, B> top {A{ 1,1},B{1,1}};
Questions:
1) Is there maybe a simpler way to determine the parameter list for the class
hierarchy. My way with typedef typename TypeConcatenate<typename Head::Parms, typename Unroll < Base, Next...>::AllParms>::type AllParms;
looks a bit hard :-)
2) Because of 1) I have a kind of type container which holds T...
and the problem with my constructor arise with the unpacking of the parameter list which is contained in a container. Maybe my solution is much to complex. Nay hint to solve the basic idea?
3) Ignoring that the problems of 1) and 2) are comes from a totally boring design I want to know which I couldn’t specialize the constructor with
template <typename Base, typename ... Next, typename ... T>
Top<Base, Next...>::Top< TypeContainer<T...>>( T... args) {}
For any further discussion: Yes, I know that the parameters should be forwarded and not given as value an so on. But I want to simplify the example which seems long enough for the discussion.