Reputation: 38654
Is it possible to write a variadic template class
template<typename Functor, int... D>
struct Foo
{
void bar()
{
// ???
}
};
Which is equivalent to
template<typename Functor, int D0>
struct Foo<Functor, D0>
{
void bar()
{
Functor f;
double d0[D0];
f(d0);
}
};
template<typename Functor, int D0, int D1>
struct Foo<Functor, D0, D1>
{
void bar()
{
Functor f;
double d0[D0];
double d1[D1];
f(d0, d1);
}
};
// And so on...
That is, the number of arguments to pass to the functor is equal to the number of template arguments. The arguments should be allocated on the stack.
Upvotes: 0
Views: 454
Reputation: 217850
Following a version with the arguments on the stack through a std::tuple
:
// Helper class to be able to use expansion of std::get<Index>(tuple)
template <int... Is> struct index_sequence {};
// Following create index_sequence<0, 1, 2, .., sizeof...(Is) - 1>
template <int Index, int... Is>
struct make_index_sequence { // recursively build a sequence of indices
typedef typename make_index_sequence<Index - 1, Index -1, Is...>::type type;
};
template <int... Is>
struct make_index_sequence<0, Is...> { // stop the recursion when 0 is reached
typedef index_sequence<Is...> type;
};
template<typename Functor, int... Ds>
struct Foo
{
void bar()
{
bar(typename make_index_sequence<sizeof...(Ds)>::type());
}
private:
template <int... Is>
void bar(index_sequence<Is...>)
{
Functor f;
std::tuple<double[Ds]...> t; // std::tuple<doudle[D0], double[D1], ..>
f(std::get<Is>(t)...); // f(std::get<0>(t), std::get<1>(t), ..);
}
};
Upvotes: 5
Reputation: 2874
Maybe this works:
template <typename Functor, int i, int... others>
struct Foo
{
template <typename ...T>
void bar(T ... rest)
{
double d[i];
Foo<Functor, others...> foo;
foo.bar(rest..., d);
}
};
template <typename Functor, int i>
struct Foo<Functor, i>
{
template <typename ...T>
void bar(T ... rest)
{
double d[i];
Functor f;
f(d, rest...);
}
};
Upvotes: 0
Reputation: 55897
Is that what you want?
template<typename Functor, int... D>
struct Foo
{
template<std::size_t N>
std::array<double, N> create()
{
return std::array<double, N>();
}
void bar()
{
Functor f;
f(create<D>()...);
}
};
Upvotes: 2