tupleを展開して、関数の引数にする。
したいこと。
int main() { auto x = std::make_tuple(1, 2.0, "three"); auto f = [](auto a, auto b, auto c) { std::cout << typeid(a).name() << std::endl; std::cout << typeid(b).name() << std::endl; std::cout << typeid(c).name() << std::endl; }; apply(f, x); return 0; }
上記のようにapplyに関数とtupleを渡した時に、下記のように関数を評価したい。
f(1, 2.0, "three");
variadic templateを再帰的に呼び出すことによって、tupleの中身を順次Args&... argsに貯める。最後に関数fに渡す。
template <int N> struct Expand { template <typename F, typename Tuple, typename... Args> static void apply(F& f, Tuple& t, Args&... args) { Expand<N - 1>::apply(f, t, std::get<N - 1>(t), args...); } }; template <> struct Expand<0> { template <typename F, typename Tuple, typename... Args> static void apply(F& f, Tuple& t, Args&... args) { f(args...); } }; template <typename F, typename Tuple> void apply(F& f, Tuple& t) { Expand<std::tuple_size<Tuple>::value>::apply(f, t); }
実行イメージ
Expand<3>::apply(f, x)
Expand<2>::apply(f, x, "three")
Expand<1>::apply(f, x, 2.0, "three")
Expand<0>::apply(f, x, 1, 2.0, "three")
f(1, 2.0, "three")