2017-01-10 9 views
4

今日、私は(少なくとも私にとっては)タプルをコンパイル時に作成しようとしています。ラップされたバリアブル型のタプルを作成する

私は、いくつかの基本的な構造体を持っているとしましょう:

struct Foo1 { int data; }; 
struct Foo2 { int data; }; 
struct Foo3 { int data; }; 

、別の構造体が、いくつかのテンプレートのものと:

template < typename T, 
      size_t Size > 
struct Metadata { 

    using type = T; 

    std::bitset<Size> bitset; 
}; 

だから今、私は、タプルのこの種を作成します:

constexpr std::tuple<Metadata<Foo1, 3>, Metadata<Foo2, 3>, Metadata<Foo3, 3>> test { {0}, {0}, {0}}; 

しかし、自動では、次のようになります。

template < typename ... Ts > 
constexpr auto make_metadata() { 

    return std::tuple<Metadata<Foo1, sizeof...(Ts)>, 
        Metadata<Foo2, sizeof...(Ts)>, 
        Metadata<Foo3, sizeof...(Ts)>>{{0},{0},{0}}; 
} 

まあ、最後のコードはそれほど良いものではないので、私はそのようなものを持っていますが自動です。たぶん、tuple_catとfold式があるかもしれませんが、少し失われています。だから、誰かが答えを知っていれば:)

答えて

3

あなたは意味する...を使用することができます1つの式の中に複数のものがあります。このケースでは、両方のすぐと非すぐTsを展開したい:あなたはそれをこれを書くことのために、それが明確になる場合

template <class... Ts> 
constexpr auto make_metadata() 
{ 
    return std::make_tuple(Metadata<Ts, sizeof...(Ts)>{0}...); 
} 

はまた、あなたがは、単一のライン上のすべてを書くことを持っていませんway:

template <class... Ts> 
constexpr auto make_metadata() 
{ 
    constexpr size_t N = sizeof...(Ts); 
    return std::make_tuple(Metadata<Ts, N>{0}...); 
} 
+0

C++のようです。17 std :: make_tupleを明示的に置く必要はありません。しかし、あなたとギヨームのおかげで、とにかく:) –

+0

@MathieuVanNevelもちろん、5文字を保存して 'std :: tuple(...)'と書くことができます。 – Barry

2

std::make_tupleとシンプルな可変引数テンプレート展開は十分でしょう。

template <typename... Ts> 
constexpr auto make_metadata() { 
    return std::make_tuple(Metadata<Ts, sizeof...(Ts)>{0}...); 
} 
1

以下は、あなたが欲しいものを行う必要があります。

template <typename T> struct tag {}; 

template <typename ... Ts> 
constexpr auto make_metadata() { 

    return std::tuple<Metadata<Ts, sizeof...(Ts)>...>{{(tag<Ts>{}, 0)}...}; 
} 
関連する問題