繁体   English   中英

在模板化类的模板化构造函数中扩展参数包

[英]expanding parameter pack in templated constructor of templated class

在描述问题之前,我将向您介绍我的工作目标是什么。

我想要一个模板来创建一个类(同时递归展开类型列表),该类从各种参数列表中的所有给定类型派生。 很好 (见下文)

现在,我的目标是通过展开模板中的“自动”创建的类型向子类的所有构造函数提供所有参数。 最后,每个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;方式typedef typename TypeConcatenate<typename Head::Parms, typename Unroll < Base, Next...>::AllParms>::type AllParms; 看起来有点难:-)

2)由于1)我有一种类型容器,它容纳T... ,而我的构造函数出现问题的原因是容器中包含的参数列表的解压缩。 也许我的解决方案非常复杂。 否暗示要解决基本思路?

3)忽略1)和2)的问题来自于一个完全无聊的设计,我想知道我不能专门使用哪个构造函数

template <typename Base, typename ... Next, typename ... T>
Top<Base, Next...>::Top< TypeContainer<T...>>( T... args) {}

对于任何进一步的讨论:是的,我知道应该转发参数,而不是将其作为值给出等等。 但是我想简化这个例子,这个例子似乎足够长。

听起来您需要可变的转发构造函数,例如:

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) {}

仍然没有任何意义,无法从T... args推导TypeContainer<T...>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM