これを実現するには、いくつかのテンプレートメタプログラミング機構が必要です。
引数ディスパッチを実現する最も簡単な方法は、整数のパックされたコンパイル時シーケンスを含む式でパック拡張を利用することです。このようなシーケンスを構築するには、テンプレート機構が必要です(このようなシーケンスを標準化する提案の詳細については、この回答の最後にある注釈も参照してください)。
index_range
整数のコンパイル時の範囲[M、N)をカプセル化するクラス(テンプレート)とindex_list
整数のコンパイル時のリストをカプセル化するクラス(テンプレート)があるとすると、次のように使用します。
template<typename T, typename... Args>
struct foo
{
tuple<Args...> args;
// Allows deducing an index list argument pack
template<size_t... Is>
T gen(index_list<Is...> const&)
{
return T(get<Is>(args)...); // This is the core of the mechanism
}
T gen()
{
return gen(
index_range<0, sizeof...(Args)>() // Builds an index list
);
}
};
そして、ここにとの可能な実装がindex_range
ありindex_list
ます:
//===============================================================================
// META-FUNCTIONS FOR CREATING INDEX LISTS
// The structure that encapsulates index lists
template <size_t... Is>
struct index_list
{
};
// Collects internal details for generating index ranges [MIN, MAX)
namespace detail
{
// Declare primary template for index range builder
template <size_t MIN, size_t N, size_t... Is>
struct range_builder;
// Base step
template <size_t MIN, size_t... Is>
struct range_builder<MIN, MIN, Is...>
{
typedef index_list<Is...> type;
};
// Induction step
template <size_t MIN, size_t N, size_t... Is>
struct range_builder : public range_builder<MIN, N - 1, N - 1, Is...>
{
};
}
// Meta-function that returns a [MIN, MAX) index range
template<unsigned MIN, unsigned MAX>
using index_range = typename detail::range_builder<MIN, MAX>::type;
また、クラステンプレートを標準化するという、 Jonathan Wakelyによる興味深い提案が存在することにも注意してください。これは、私がここで呼んだものと非常によく似ています。int_seq
index_list