#pragma once // blindly copypasted from StackOverflow (to allow std::function to store the funcref types with their move semantics) template struct shared_function { std::shared_ptr f; shared_function() = default; shared_function(F&& f_) : f(std::make_shared(std::move(f_))) { } shared_function(shared_function const&) = default; shared_function(shared_function&&) = default; shared_function& operator=(shared_function const&) = default; shared_function& operator=(shared_function&&) = default; template auto operator()(As&&... as) const { return (*f)(std::forward(as)...); } }; template shared_function> make_shared_function(F&& f) { return { std::forward(f) }; }