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")