3

C++ 2011 コードでトリッキーなものが必要です。現在、私はこの種のメタ関数を持っています:

template<unsigned int N, unsigned int M> 
static constexpr unsigned int myFunction()

Nこの関数は、とに基づいて数値を生成できますM

N入力とを使用してメタ関数を作成したいと思います。Mこれは、 をデクリメントすることにより、可変個引数テンプレートを再帰的に構築しますM。たとえば、この関数を で呼び出すと、 equal とM = 3呼ばれる可変個引数テンプレートが構築されます。List

List... = myFunction<N, 3>, myFunction<N, 2>, myFunction<N, 1>, myFunction<N, 0>

それを行う方法(もちろん可能であれば)?

4

1 に答える 1

4

既存のタプルパックジェネレーターを使用するのがおそらく最も簡単です。

// Idiomatic tuple pack generator using successor method
template<int... I> struct tuple_pack {
    using succ = tuple_pack<I..., sizeof...(I)>;
};
template<int N> struct make_tuple_pack {
    using type = typename make_tuple_pack<N - 1>::type::succ;
};
template<> struct make_tuple_pack<0> {
    using type = tuple_pack<>;
};

これで、タプルパックジェネレーターを適用して、実装関数に委任できます。

template<int N, int M, typename T> struct foo_impl {};
template<int N, int M, int... I> struct foo_impl<N, M, tuple_pack<I...>> {
    static void foo() {
        int arr[M] = { myFunction<N, M - I>()... };
    }
};
template<int N, int M> void foo() {
    foo_impl<N, M, typename make_tuple_pack<M>::type>::foo();
}

クラステンプレートの特殊化よりも関数パラメータの推論を好む場合、これは次のように書くこともできます。

template<int N, int M, int... I> void foo_impl(tuple_pack<I...>) {
    int arr[M] = { myFunction<N, M - I>()... };
}
template<int N, int M> void foo() {
    foo_impl<N, M>(typename make_tuple_pack<M>::type{});
}

配列サイズをint arr[M];として指定する必要がありました。それがパック拡張初期化子の標準で要求されているのか、それともgccのバグなのかわからない。いずれにせよ、それは大きな面倒ではありません。

于 2012-09-05T15:31:35.647 に答える