Last active
November 15, 2025 21:50
-
-
Save dgodfrey206/ac9c7c201a26407396f1a37626f9a183 to your computer and use it in GitHub Desktop.
std::function implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Source - https://stackoverflow.com/a/79821144 | |
| // Posted by David G | |
| // Retrieved 2025-11-15, License - CC BY-SA 4.0 | |
| template<class Sig> | |
| struct function_sig; | |
| template<class R, class... Args> | |
| struct function_sig<R(Args...)> { | |
| template<class F> | |
| requires (!std::same_as<F, function_sig>) | |
| function_sig(F&& f) : | |
| pf(std::make_unique<Callable<F>>(std::forward<F>(f))) | |
| { } | |
| function_sig()=default; | |
| function_sig(function_sig&& o) = default; | |
| function_sig& operator=(function_sig&& o) = default; | |
| R operator()(Args... args) const { | |
| return pf->invoke(std::forward<Args>(args)...); | |
| } | |
| struct ICallable { | |
| virtual R invoke(Args...) const = 0; | |
| virtual ~ICallable() = default; | |
| }; | |
| template<class C> | |
| struct Callable : ICallable { | |
| C c_; | |
| Callable(C c) : c_(std::move(c)) { } | |
| R invoke(Args... args) const { | |
| return c_(std::forward<Args>(args)...); | |
| } | |
| }; | |
| private: | |
| std::unique_ptr<ICallable> pf; | |
| }; | |
| template<class T> | |
| struct get_sig : get_sig<decltype(&T::operator())> { }; | |
| template<class R, class... Args> | |
| struct get_sig<R(*)(Args...)> : std::type_identity<R(Args...)> { }; | |
| template<class R, class C, class... Args> | |
| struct get_sig<R(C::*)(Args...)> : std::type_identity<R(Args...)> { }; | |
| template<class R, class C, class... Args> | |
| struct get_sig<R(C::*)(Args...) const> : std::type_identity<R(Args...)> { }; | |
| template<class T> | |
| using get_sig_t = typename get_sig<T>::type; | |
| template<class C, class Sig=get_sig_t<std::decay_t<C>>> | |
| function_sig<Sig> make_function(C&& c) { | |
| return { std::forward<C>(c) }; | |
| } | |
| int main() { | |
| auto m = make_function(const_int_func); | |
| auto m2 = make_function(int_arry_func); | |
| auto l = make_function([](int a, int b) { std::println("{} * {} = {}", a, b, a * b); }); | |
| int val = 5; | |
| int vals[2] = { 1, 2 }; | |
| m(&val); | |
| m2(vals); | |
| l(2, 2); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment