Sometimes you have a tuple and want to pass its contents to a function as arguments. One way is to overload the function:
int average(int a, int b, int c) { return (a + b + c) / 3; } int average(std::tuple<int,int,int> x) { return average(std::get<0>(x), std::get<1>(x), std::get<2>(x)); }
This works for an individual function or two, but it isn't a general solution and it doesn't scale. So let's automate it.
#include <functional> #include <tuple> namespace detail { template<std::size_t... Indices> struct indices { typedef indices<Indices...,sizeof...(Indices)> next; }; // Generates the type indices<0,1,...,N-1> which is used to unpack an N-tuple. 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; }; // We use the indices to unpack the tuple. template<class Function, class... T, std::size_t... Indices> inline typename std::result_of<Function(T...)>::type apply(Function f, std::tuple<T...>&& x, indices<Indices...>) { return f(std::forward<T>(std::get<Indices>(x))...); } } // namespace detail // Apply function f to the contents of tuple x. template<class Function, class... T> inline typename std::result_of<Function(T...)>::type apply(Function f, std::tuple<T...>&& x) { typedef typename detail::make_indices<sizeof...(T)>::type Indices; return detail::apply(f, std::forward<std::tuple<T...>>(x), Indices()); }
Now we can call our functions this way:
int average(int a, int b, int c) { return (a + b + c) / 3; } int zero() { return 0; } int main() { std::cout << apply(average, std::make_tuple(1, 2, 3)) << '\n'; std::cout << apply(zero, std::make_tuple()) << '\n'; std::cout << apply([](int x, int y){ return x + y; }, std::make_tuple(2, 3)) << '\n'; }