#include <iostream>
#include <typeinfo>

struct A {};
struct B {};
struct C {};
struct D {};
struct E {};

struct F
{
    template <typename T>
    void operator () (T&& t) {
        std::cout << typeid(t).name() << std::endl;
    }

};

template <typename F, typename...Ts>
void apply(F f, Ts&&...args) {
    const int dummy[] = { (f(std::forward<Ts>(args)), 0)... };
    static_cast<void>(dummy); // avoid warning about unused variable.
}

int main() {

    A a;
    B b;
    C c;
    D d;
    E e;

    apply(F{}, a, b, c, d, e);
    return 0;
}
