One approach:
#define TUPLE_VALUES_1(t) std::get<0>(t)
#define TUPLE_VALUES_2(t) TUPLE_VALUES_1(t), std::get<1>(t)
#define TUPLE_VALUES_3(t) TUPLE_VALUES_2(t), std::get<2>(t)
f(TUPLE_VALUES_2(t));
Update
The link from T.C.'s comment has a much better solution. By adding a wrapper function around it, you can get what you were hoping for.
#include <tuple>
#include <iostream>
using std::cout;
using std::endl;
// --------------------
// BEGIN borrowed code
// --------------------
template<int ...> struct seq {};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};
template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };
template <typename Ret, typename ...Args>
struct Dispatcher
{
template<int ...S>
Ret callFunc(seq<S...>)
{
return func_(std::get<S>(params_) ...);
}
std::tuple<Args...> params_;
Ret (*func_)(Args...);
};
// --------------------
// END borrowed code
// --------------------
// Wrapper function
template <typename Ret, typename ...Args>
Ret callFunc(std::tuple<Args...> t, Ret (*func)(Args...))
{
Dispatcher<Ret, Args...> disp = {t, func};
return disp.callFunc(typename gens<sizeof...(Args)>::type());
}
// ---------------------
// BEGIN Test functions
// ---------------------
double foo(int x, float y, double z)
{
return x + y + z;
}
int bar(int a, int b)
{
return a + b;
}
void baz(int a)
{
}
void test1()
{
auto t = std::make_tuple<int, float, double>(1, 1.2, 5);
cout << callFunc(t, foo) << endl;
}
void test2()
{
auto t = std::make_tuple<int, int>(1, 2);
cout << callFunc(t, bar) << endl;
}
void test3()
{
auto t = std::make_tuple<int>(2);
callFunc(t, baz);
}
// ---------------------
// END Test functions
// ---------------------
int main(void)
{
// Test the functionality
test1();
test2();
test3();
}