#pragma once #include template class Function; template class Function { private: class callable_base { public: virtual Ret call(Args...) const = 0; virtual ~callable_base() = default; }; template class callable : public callable_base { private: Fun _fun; public: callable(Fun fun):_fun(fun) {} virtual Ret call(Args... args) const override { return _fun(std::forward(args)...); } virtual ~callable() override {} }; std::unique_ptr _fun; bool _is_null = false; public: Function() {} template Function& operator=(Fun fun) { _fun = std::make_unique>(fun); _is_null = false; return *this; } Function& operator=(std::nullptr_t) { _is_null = true; return *this; } Ret operator()(Args... args) const { if (_is_null) throw std::bad_function_call(); return _fun->call(std::forward(args)...); } operator bool() const { return static_cast(_fun); } };