I have function at
designed to access std::tuple element by index specified in runtime
template
Assuming you pass something similar to a generic lambda, i.e. a function object with an overloaded function call operator:
#include <iostream>
struct Func
{
template<class T>
void operator()(T p)
{
std::cout << __PRETTY_FUNCTION__ << " : " << p << "\n";
}
};
The you can build an array of function pointers:
#include <tuple>
template<int... Is> struct seq {};
template<int N, int... Is> struct gen_seq : gen_seq<N-1, N-1, Is...> {};
template<int... Is> struct gen_seq<0, Is...> : seq<Is...> {};
template<int N, class T, class F>
void apply_one(T& p, F func)
{
func( std::get<N>(p) );
}
template<class T, class F, int... Is>
void apply(T& p, int index, F func, seq<Is...>)
{
using FT = void(T&, F);
static constexpr FT* arr[] = { &apply_one<Is, T, F>... };
arr[index](p, func);
}
template<class T, class F>
void apply(T& p, int index, F func)
{
apply(p, index, func, gen_seq<std::tuple_size<T>::value>{});
}
Usage example:
int main()
{
std::tuple<int, double, char, double> t{1, 2.3, 4, 5.6};
for(int i = 0; i < 4; ++i) apply(t, i, Func{});
}
clang++ also accepts an expansion applied to a pattern that contains a lambda expression:
static FT* arr[] = { [](T& p, F func){ func(std::get<Is>(p)); }... };
(although I've to admit that looks really weird)
g++4.8.1 rejects this.