#include <utility>
#include <iostream>
#include <tuple>    


template<int...> struct seq {};
template<int Min, int Max, int... s> struct make_seq:make_seq<Min, Max-1, Max-1, s...> {};
template<int Min, int... s> struct make_seq<Min, Min, s...> {
  typedef seq<s...> type;
};
template<int Max, int Min=1>
using MakeSeq = typename make_seq<Min, Max>::type;

template<typename Func, typename Tuple, int... s>
void do_call( Func&& f, seq<s...>, Tuple&& tup ) {
  std::forward<Func>(f)( std::get<s>(std::forward<Tuple>(tup))... );
}

typedef void(*pvoidary)(void*);

template<typename Lambda>
struct pvoidary_factory {
  Lambda func;
  pvoidary_factory( Lambda const& f ):func(f) {}
  pvoidary_factory( pvoidary_factory const& ) = default;
  pvoidary_factory( pvoidary_factory && ) = default;
  template<typename... Args>
  std::tuple<pvoidary, void*> operator()(Args&&... args) const {
    typedef std::tuple<Lambda, Args...> package;
    void* pVoid = new package(func, std::forward<Args>(args)...);
    return std::make_tuple(
      [](void* pVoid) {
        package* pPack = reinterpret_cast<package*>(pVoid);
        do_call( std::get<0>(*pPack), MakeSeq<sizeof...(Args)+1, 1>(), *pPack );
      },
      pVoid
    );
  }
};
template<typename Lambda>
pvoidary_factory<Lambda> Wrap( Lambda const& func ) {
  return {func};
}

int main() {
  int x = 7;
  auto factory = Wrap( [x]( int y, double d ) {
    std::cout << "X:" << x << "Y:" << y << "D:" << d << "\n";
  } );
  void* pvoid;
  pvoidary pfunc; // void(*)(void*)
  std::tie( pfunc, pvoid ) = factory( 10, 3.14 ); // bind y and d here
  pfunc( pvoid ); // calls the wrapped method
}