Initially, something worked a while ago. So try the following code:
template<unsigned N, unsigned M> struct call_up_impl{ template<class Func, class Mutator, class Tuple, class... Args> static void do_call(const Func& func, const Mutator& mutator, const Tuple& args, Args&&... unpacked_args) { call_up_impl<N-1, M>::do_call(func, mutator, args, std::get<N-1>(args), std::forward<Args>(unpacked_args)...); } }; template<unsigned M> struct call_up_impl<0, M> { template<class Func, class Mutator, class Tuple, class... Args> static void do_call(const Func& func, const Mutator&, const Tuple&, Args&&... unpacked_args) { func(std::forward<Args>(unpacked_args)...); } }; template<unsigned M> struct call_up_impl<M, M> { template<class Func, class Mutator, class Tuple, class... Args> static void do_call(const Func& func, const Mutator& mutator, const Tuple& args, Args&&... unpacked_args) { call_up_impl<M-1, M>::do_call(func, mutator, args, mutator(std::get<M-1>(args)), std::forward<Args>(unpacked_args)...); } }; template<int i, typename Function, typename... Parms> void apply(Function f, Parms... parms) { std::tuple<Parms...> t(parms...); call_up_impl<std::tuple_size<decltype(t)>::value, i + 1>::do_call(f, &g, t); }
This is a quick adaptation of my source code, so it has not passed a thorough check and may not be the best way to do this, but it should work at least (at least for a quick test and depending on what exactly you want). It should be possible to do this without a tuple, but I didn’t get it for compilation with g ++ (it doesn’t like nested variation templates). However, changing apply to:
template<int i, typename Function, typename... Parms> void apply(Function f, Parms&&... parms) { std::tuple<Parms&&...> t(std::forward<Parms>(parms)...); call_up_impl<std::tuple_size<decltype(t)>::value, i + 1>::do_call(f, &g, t); }
likely to escape most of the overhead entered by the tuple. It would be even better to properly forward the results of std::get calls, but I'm too tired to work on it now.