I would like to create a function that takes a variable number of template arguments. Later with these arguments the function should pass their position like this:
template<typename R, typename Args...>
R myFunction(Data &data, void *function) {
auto f = (R (*)(Args...))function;
return f(read<Args1>(data, 1), read<Args2>(data, 2), ...);// <-- This is the problem
}
The given code is of course not compilable. Is there any way to fix it? Is there a way to do it without variadic templates without too much code duplication?
Yes, that is possible:
With these helpers, you need one forwarder for your function like this:
EDIT: How does it work? First, we determine the size of the argument pack
Args
throughsizeof...
.make_indices<N>::type
then expands intoindices<0,1,2,...,N-1>
. It is given as an additional parameter to the implementation function (from the forwarder who just creates a dummy instance), hence argument deduction kicks in on the implementation function's side and puts the generated indices into the argument packNs
.The implementation function now has two argument packs with the same size, namely
Args
andNs
. When expanded through the ellipsis...
, the ellipsis expands the whole expression that it's applied to and it expands all parameter packs in parallel! In the above example that expression isread<Args>(Data, Ns+1)
, which nicely expands into the OPs pseudo-code.