#include <iostream>
#include <functional>

template<size_t... indexes>
struct index_tuple {};

template<size_t head, size_t... indexes>
struct index_tuple<head, indexes...> {
    typedef typename index_tuple<head-1, head-1, indexes...>::type type;
};

template<size_t... indexes>
struct index_tuple<0, indexes...> {
    typedef index_tuple<indexes...> type;
};

template<typename... Args>
struct index_tuple_maker {
    typedef typename index_tuple<sizeof...(Args)>::type type;
};
    

template< typename ... Args >
class Message {
public:
    Message( Args&& ... args ) {
        mArgs = std::make_tuple( args ...  );
    }

    std::tuple< Args ... > mArgs;
    typedef std::function< void ( Args ... ) > HandlerType;

    void Consume( const HandlerType &handler ) {
        Consume(handler, typename index_tuple_maker<Args...>::type());
    }
    
    template<size_t... ns>
    void Consume(const HandlerType &handler, index_tuple<ns...>) {
        handler(std::get<ns>(mArgs)...);
    }
};


int main() {
    Message<int, int> msg(1, 2);

    msg.Consume( [] ( int i, int j ) {
        std::cout << i << ',' << j << '\n';
    });
}
