#include <iostream>

template<class T>using type=T;
template<class F>
struct callback_t;

template<class F, class Sig>
struct cast_helper_pvoid_last;
template<class F, class R, class... Args>
struct cast_helper_pvoid_last<F, R(Args...)> {
  type<R(*)(Args..., void*)> operator()() const {
    return [](Args... args, void* pvoid)->R {
      auto* callback = static_cast<callback_t<F>*>(pvoid);
      return callback->f( std::forward<Args>(args)... );
    };
  }
};

template<class F>
struct callback_t {
  F f;
  void* pvoid() { return this; }

  template<class Sig>
  auto pvoid_at_end()->decltype( cast_helper_pvoid_last<F, Sig>{}() ) {
    return cast_helper_pvoid_last<F,Sig>{}();
  }
};
template<class T>using decay_t=typename std::decay<T>::type;
template<class F>
callback_t<decay_t<F>> make_callback( F&& f ) { return {std::forward<F>(f)}; }

int main() {
	int x = 3;
	auto callback = make_callback( [&]( int y ) { return x+y; } );
	int (*func)(int, void*) = callback.pvoid_at_end<int(int)>();
	std::cout << func( 1, callback.pvoid() ) << "\n";
}