Passing Variadic template argument position

I would like to create a function that takes a variable number of template arguments. Later, with these arguments, the function should move to the following position:

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 } 

This code, of course, cannot be compiled. Is there any way to fix this? Is there a way to do this without variation patterns without excessive code duplication?

+8
c ++ c ++ 11 variadic-templates
source share
1 answer

Yes it is possible:

 // we need a compile-time helper to generate indices template< std::size_t... Ns > struct indices { typedef indices< Ns..., sizeof...( Ns ) > next; }; template< std::size_t N > struct make_indices { typedef typename make_indices< N - 1 >::type::next type; }; template<> struct make_indices< 0 > { typedef indices<> type; }; 

With these helpers, you need one forwarder for your function:

 template<typename R, typename... Args, std::size_t... Ns> R myFunctionImpl(void *Data, void *function, indices<Ns...> ) { auto f = (R (*)(Args...))function; return f(read<Args>(Data, Ns + 1)...);// +1 because indices is zero-based } template<typename R, typename... Args> R myFunction(void *Data, void *function) { return myFunctionImpl< R, Args... >( Data, function, typename make_indices<sizeof...(Args)>::type() ); } 

EDIT: How does it work? First, we determine the size of the package of Args arguments through sizeof... make_indices<N>::type then expanded to indices<0,1,2,...,N-1> . It is set as an additional parameter for the implementation function (from the forwarder, which only creates a dummy instance), therefore, the deduction argument is launched on the side of the implementation function and places the generated indexes in the package of arguments Ns .

The implementation function now has two packages of arguments with the same size, namely Args and Ns . When expanding with an ellipse ... , the ellipsis expands the entire expression to which it applies, and simultaneously expands all the parameter packets! In the above example, this is the read<Args>(Data, Ns+1) expression, which extends perfectly into the OP pseudo-code.

+14
source share

All Articles