#include <iostream>
#include <tuple>
#include <type_traits>

#if 1 // Not in C++11 // make_index_sequence
#include <cstdint>

template <std::size_t...> struct index_sequence {};

template <std::size_t N, std::size_t... Is>
struct make_index_sequence : make_index_sequence<N - 1, N - 1, Is...> {};

template <std::size_t... Is>
struct make_index_sequence<0u, Is...> : index_sequence<Is...> {};

#endif // make_index_sequence

template <typename TReturn, typename...TArgs>
struct SomeFunction{
    using ReturnType = TReturn;
    using ArgTypes = std::tuple<TArgs...>;

    TReturn operator () (TArgs... args) const
    {
        const int dummy[] = {0, ((std::cout << args),0 )...};
        static_cast<void>(dummy);
    }
};



template <typename TFunction, typename TupleArg = typename TFunction::ArgTypes>
class Task;


template <typename TFunction, typename... TArgs>
class Task<TFunction, std::tuple<TArgs...>>
{
public:
    Task(TFunction fun, TArgs...args) : fun_(fun), args_(args...) {}
    void operator()()
    {
        call(make_index_sequence<sizeof...(TArgs)>{});
    }
private:
    template <std::size_t ... Is>
    void call(index_sequence<Is...>)
    {
        fun_(std::get<Is>(args_)...);
    }
private:
    TFunction fun_;
    std::tuple<TArgs...> args_;
};

int main()
{
    SomeFunction<void, int, char> f;
    Task<SomeFunction<void, int, char>> task(f, 42, 'c');

    task();

    return 0;
}
