#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;
}