在我描述问题之前,我会告诉你我的工作目标是什么。
我希望有一个模板来创建一个类(同时以递归方式展开一个类型列表),该模板派生出一个可变参数列表中的所有给定类型。这很好。 (见下文)
现在我的目标是通过展开模板中的“自动”创建类型向所有子类构造函数提供所有参数。最后,每个Unroll类都应该使用创建给定类实例所需的参数。每个递归创建的模板实例都应该使用TypeContainer中包含的一个参数包。
在你提问之前:这段代码只是学术上学习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}};
问题:
1)是否有更简单的方法来确定类的参数列表
层次结构。我typedef typename TypeConcatenate<typename Head::Parms, typename Unroll < Base, Next...>::AllParms>::type AllParms;
的方式看起来有点困难: - )
2)由于1)我有一种类型容器,它包含T...
,并且我的构造函数的问题出现在解包容器中包含的参数列表中。也许我的解决方案很复杂。 Nay暗示要解决这个基本想法吗?
3)忽略1)和2)的问题来自于一个完全无聊的设计我想知道哪些我不能专门构造者
template <typename Base, typename ... Next, typename ... T>
Top<Base, Next...>::Top< TypeContainer<T...>>( T... args) {}
对于任何进一步的讨论:是的,我知道应该转发参数而不是作为值给出等等。但我想简化一个看起来足够讨论的例子。
答案 0 :(得分:0)
听起来你想要一个可变的转发构造函数,例如:
template <typename... Ts>
class lots_of_parents : public Ts...
{
public:
template <typename... Args>
lots_of_parents(Args&&... args) : Ts(std::forward<Args>(args))... {}
};
lots_of_parents<A, B> mytop {A{1, 1}, B{1, 1}};
以及(a)问题的其余部分是XY问题,或者(b)我只是不理解。
编辑:错过了有关构造函数的问题。暂时忽略函数不能部分专门化,我认为语法看起来像:template <typename Base, typename ... Next>
template <typename ... T>
Top<Base, Next...>::Top< TypeContainer<T...>>( T... args) {}
这仍然没有意义,没有办法从TypeContainer<T...>
中推断T... args
。