Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Last active November 15, 2025 21:50
Show Gist options
  • Select an option

  • Save dgodfrey206/ac9c7c201a26407396f1a37626f9a183 to your computer and use it in GitHub Desktop.

Select an option

Save dgodfrey206/ac9c7c201a26407396f1a37626f9a183 to your computer and use it in GitHub Desktop.
std::function implementation
// 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