2017-11-29 19 views
0

私はテンプレートとintのリストの実装を持っている:操作は[C++ 11]

私は IntListで動作するようにメタ関数を定義したい
template<int ... Int> 
struct IntList; 

template<int H, int ... T> 
struct IntList<H, T...>{ 
    static const int Head = H; 
    using Tail = IntList<T...>; 
}; 
template<> 
struct IntList<>{}; 

IntConsリストを増やすことができます0から使用のN-1(例にint型で長さNのリストを生成することを可能にする一つの要素、及びGenerateによって:

template<int H, typename IL> 
struct IntCons; 

template<int H, int... Tail> 
struct IntCons<H, IntList<Tail...>>{ 
    using type = IntList<H, Tail...>; 
}; 
using L = Generate<5>::type; // IntList<0,1,2,3,4>) Iは IntConsこの方法を定義します

私はこのような方法でIntConsを使用するようなメタ機能Generateを定義することはできません。 ここでヒントは、私はGenerateのデフォルトパラメータを使用する必要がありますによると。

メタ機能を定義する方法は何ですか、どのように実装できますか?

+0

何を試しましたか?何がうまくいかない? – Barry

+0

@バリー私は何をする必要があるのか​​理解していないので、あまり試してみませんでした。 – user1786089

答えて

1

Generatestd::make_index_sequenceと非常によく似ています。おそらく、実装を検索することができます。

楽しみのためだけに、私は(簡単だが実際には効率的ではありません)

#include <type_traits> 

template <int ...> 
struct IntList 
{ }; 

template <int N, int ... Next> 
struct Generate : public Generate<N-1, N-1, Next...> 
{ }; 

template <int ... Next> 
struct Generate<0, Next ... > 
{ using type = IntList<Next ... >; }; 

int main() 
{ 
    static_assert(std::is_same<Generate<5>::type, 
           IntList<0, 1, 2, 3, 4>>{}, "!"); 
} 

より良いアプローチ(しかし、そう単純ではない)は、次の(対数)することができ、次の線形的なアプローチを提案

template <int...> 
struct IntList 
{ }; 

template <typename, typename> 
struct ConcatLists; 

template <int ... S1, int ... S2> 
struct ConcatLists<IntList<S1...>, IntList<S2...>> 
{ using type = IntList<S1..., (sizeof...(S1)+S2)...>; }; 

template <int N> 
struct Generate 
{ using type = typename ConcatLists< 
     typename Generate<(N>>1)>::type, 
     typename Generate<N-(N>>1)>::type>::type; }; 

template<> 
struct Generate<0> 
{ using type = IntList<>; }; 

template<> 
struct Generate<1> 
{ using type = IntList<0>; }; 

int main() 
{ 
    static_assert(std::is_same<Generate<5>::type, 
           IntList<0, 1, 2, 3, 4>>{}, "!");  
} 

- EDIT -

OPが

を尋ねます

ありがとうございます。最初の例がどのように機能するか説明してください。私は、この行がどのように機能するかを理解していない:template <int N, int ... Next> struct Generate : public Generate<N-1, N-1, Next...> { };

私はそれを理解する最良の方法はGenerate<5>から、Inlist<0, 1, 2, 3, 4>にもたらす、という連鎖を次のだと思います。

Generate<5>5そうGenerateの唯一の主なバージョンが適用可能である0異なる)継承(N5あり; Next...が空である)Generate<4, 4>から。

Generate<4, 4>継承(40は異なる)(N5あり; Next...4ある)Generate<3, 3, 4>から。

今や明らかになるはずです。

Generate<3, 3, 4>を継承するGenerate<2, 2, 3, 4>

Generate<2, 2, 3, 4>Generate<1, 1, 2, 3, 4>を継承します。

Generate<1, 1, 2, 3, 4>Generate<0, 0, 1, 2, 3, 4>を継承します。

今すぐNはゼロです。 IntList<0, 1, 2, 3, 4>として定義type含まGenerate<0, 0, 1, 2, 3, 4>からGenerate<5>継承:だからGenerate試合の両方のバージョンが、部分的な特殊化(struct Generate<0, Next ... >は)我々は

struct Generate<0, 0, 1, 2, 3, 4> 
{ using type = IntList<0, 1, 2, 3, 4>; }; 

結論を持っている(Next...0, 1, 2, 3, 4である)、より特化され、使用されるものとします。

+0

ありがとうございます。最初の例がどのように機能するか説明してください。どのようにしてこの行が動作するのか分かりません:template を生成する {}; – user1786089

+1

@ user1786089 - 回答が改善されました。お役に立てれば。 – max66