#include <iostream>
#include <memory>
#include <tuple>
 
template< class ReturnType, class... ParamTypes>
struct move_function_base{
  virtual ReturnType callFunc(ParamTypes... p) = 0;
};
 
template<class F, class ReturnType, class... ParamTypes>
class move_function_imp : public move_function_base<ReturnType, ParamTypes...> {
 
  typename std::remove_reference<F>::type f_;
 
public:
  virtual ReturnType callFunc(ParamTypes&&... p) override {
    return f_(std::forward<ParamTypes>(p)...);
  }
  explicit move_function_imp(const F& f) : f_(f) {}
  explicit move_function_imp(F&& f) : f_(std::move(f)) {}
 
  move_function_imp() = delete;
  move_function_imp(const move_function_imp&) = delete;
  move_function_imp& operator=(const move_function_imp&) = delete;
};
 
 
template<class FuncType>
struct move_function{};
 
template<class ReturnType, class... ParamTypes>
struct move_function<ReturnType(ParamTypes...)>{
  std::unique_ptr<move_function_base<ReturnType,ParamTypes...>> ptr_;
 
  move_function() = default;
  template<class F>
  move_function(F&& f) :
    ptr_(new move_function_imp<F, ReturnType,ParamTypes...>
         (std::forward<F>(f))){}
  move_function(move_function&& other) = default;
  move_function& operator=(move_function&& other) = default;
 
  template<class... Args>
  ReturnType
  operator()(Args&& ...args)
  {
    return ptr_->callFunc(std::forward<Args>(args)...);
  }
 
  explicit operator bool() const
  {
    return static_cast<bool>(ptr_);
  }
 
  move_function(const move_function&) = delete;
  move_function& operator=(const move_function&) = delete;
};
 
int main()
{
    auto f = [](){std::cout << "Hello World" << std::endl;};
    auto f2 = move_function<void()>{f};
    return 0;
}