1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
// call fn with all but the last element of args...
template <typename Fn, typename... Args>
void f(Fn fn, Args... args)
{
// put all N arguments into a tuple
// then write out all the indices for the first N - 1 arguments
// (i.e., 0, 1, 2, ... N - 3, N - 2)
// and give them to f_impl through its template non-type parameter pack Is.
f_impl(fn,
std::make_tuple(args...),
std::make_index_sequence<sizeof...(Args) - 1>());
}
template <typename Fn, typename Args,
std::size_t... Is>
void f_impl(Fn fn, Args args, std::index_sequence<Is...>)
{
// Here Is... is a list (0, 1, 2, ..., N - 3, N - 2) of integers
// Args is no longer a pack, but rather a single tuple of all the arguments
// Now std::get<Is>(args)... is a comma-separated list of
// std::get<0>(args), std::get<1>(args), ..., std::get<N - 3>(args), std::get<N - 2>(args)
// yielding all but the last element in the tuple.
// The last element of the tuple is
// std::get<std::tuple_size<Args>::value - 1>(args);
// Call fn() with the first N - 1 elements
fn(std::get<Is>(args)...);
}
| |