You need to map each element of a parameter pack to its index within the pack - this is the typical use case for the "index sequence trick":
template <int... I> struct index_sequence {};
template <int N, int... I>
struct make_index_sequence : make_index_sequence<N-1,N-1,I...> {};
template <int... I>
struct make_index_sequence<0, I...> : index_sequence<I...> {};
template<typename... Values, int... I>
auto getColumns(index_sequence<I...>) ->
decltype(std::make_tuple(getColumn<Values>(I)...)) {
return std::make_tuple(getColumn<Values>(I)...);
}
template<typename... Values>
auto getColumns() ->
decltype(getColumns<Values...>(make_index_sequence<sizeof...(Values)>())) {
return getColumns<Values...>(make_index_sequence<sizeof...(Values)>());
}