3

問題を説明する前に、私の仕事の対象は何かを考えてみましょう。

パラメータの可変リスト内のすべての指定されたタイプから派生するクラスを作成するテンプレートが必要です(これはタイプリストを再帰的に展開します)。それはうまくいきます。(下記参照)

ここで、展開テンプレートから「自動的に」作成された型を介して、サブクラスのすべてのコンストラクターにすべてのパラメーターを提供することが私の目標です。最後に、各 Unroll クラスは、指定されたクラスのインスタンスを作成するために必要なパラメーターを食べる必要があります。再帰的に作成された各テンプレート インスタンスは、TypeContainer に含まれるパラメーター パックの 1 つを食べる必要があります。

質問する前に: このコードは、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...あり、コンテナーに含まれるパラメーター リストをアンパックすると、コンストラクターに問題が発生します。たぶん、私の解決策は非常に複雑です。基本的なアイデアを解決するためのヒントはありませんか?

3) 1) と 2) の問題が完全に退屈な設計に由来することを無視する コンストラクターを特殊化できなかったものを知りたい

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

さらなる議論のために:はい、私はパラメータが転送されるべきであり、値として与えられないことを知っています。しかし、議論には十分長いと思われる例を単純化したいと思います。

4

1 に答える 1

1

次のような可変引数転送コンストラクターが必要なようです。

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

于 2013-08-12T15:05:27.433 に答える