#pragma once #include namespace utils { template class optional_function; template class optional_function { private: std::function func; public: optional_function() = default; optional_function(std::function f) : func(std::move(f)) { } template >> optional_function(F&& f) : func(std::forward(f)) { } optional_function& operator=(std::function f) { func = std::move(f); return *this; } Ret operator()(Args... args) const { if (func) { return func(std::forward(args)...); } if constexpr (!std::is_void_v) { return Ret(); } } explicit operator bool() const noexcept { return static_cast(func); } }; }