3

演習として、非型テンプレートint Nを使用して2つの単純な関数を記述しようとしています。最初の関数は、型TのオブジェクトのN個のコピーで構成されるタプルを作成する必要があります。次のようにしたいと思います。

template <class T, int N> 
constexpr std::tuple<T...> fun(T t) {
  return (N > 0) ? std::tuple_cat(t, fun<T, N-1>(t)) : std::make_tuple(t);
}

私もこのようなことを試みましたが失敗しました(http://liveworkspace.org/code/3LZ0Fe)。T = boolでインスタンス化できるようにしたいと思います。たとえば、次のようになります。

auto bools = fun<bool, 10> (false);

2つ目は、わずかなバリエーションである必要があります。テンプレート化された構造体Fooがあり、Foo <0>、...、Foo<N>を含むタプルを作成したいと思います。

template <int N> struct Foo {
   static const int id = N;
}

template <template <int> class T, int N> 
constexpr ??? fun2 (???) {...}

テンプレート化された関数は部分的に特殊化できないため、再帰の適切な終了を作成する方法すらわかりません。forループを使用せずに、これを完全に静的に実行したいと思います。

================================================== ================================

Sethの提案に従って、私は無限に繰り返される楽しい関数自体を書くことに固執しました。

template<typename T, int N>
typename fun_helper<T, N>::type 
fun(T t) {
  if (N > 0) 
    return typename fun_helper<T, N>::type 
      { std::tuple_cat(std::make_tuple(t), fun<T, N-1>(t)) };
  else return typename fun_helper<T, N>::type { };
}

ターミネーション付きの追加の構造体を使用することで、これを機能させることができました。

template<typename T, int N> struct fun {
  typename fun_helper<T, N>::type make(T t) {
    return typename fun_helper<T, N>::type 
      { std::tuple_cat(std::make_tuple(t), fun<T, N-1>().make(t)) };
  }
};

template<typename T> struct fun<T, 0> {
  typename fun_helper<T, 0>::type 
  make(T t) {
    return typename fun_helper<T, 0>::type { };
  }
};

呼び出しはまだ比較的不器用です:

auto conds = fun<bool, 3>().make(false);

この追加の構造体なしでそれを機能させる方法はありますか?

auto conds = fun<bool, 3>(false);
4

1 に答える 1

1

最初に、部分的な特殊化のためにsを使用してパラメーターパックを再帰的に構築できますstruct(これは#2に関連しているため、この方法で示します)。このコードはテストされておらず、要素のデフォルト値を処理しませんが、アイデアが得られ、デフォルト値のコードを簡単に追加できます。

template<typename T, int N, typename... Rest>
struct fun_helper {
    typedef typename fun_helper<T, N - 1, T, Rest...>::type type;
};

template<typename T, typename... Rest>
struct fun_helper<T, 0, Rest...> {
    typedef std::tuple<Rest...> type;
};

template<typename T, int N>
typename fun_helper<T, N>::type fun() {
    return typename fun_helper<T, N>::type { };
}

int2つ目は、上記の手法をsのパラメータパックと組み合わせて、を使用して次の...ように展開できます。

Foo<Ints>...

これはに拡張されます

Foo<Int1>, Foo<Int2>, ...

あなたの関数で。

于 2013-01-30T04:22:32.500 に答える