#include #include #include // Problem: Pass a function as an argument // 1. function pointer (old & C-style) // Ugly but somewhat nice as it is very simple. See https://cdecl.org // BTW: https://www.youtube.com/watch?v=6eX9gPithBo namespace solution1 { // We want to pass this one to function foo. char *produce_str(int, double, char *) { return 0; } void foo(char *(*produce_str_callback)(int, double, char *)) { printf("produced: %s\n", (*produce_str_callback)(1, 3.14, 0)); } } // 2. template with lambda ( void foo(T fun) { fun(); } // How to pass arguments? Ugly - see perfect forwarding: https://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/. template void foo2(Fun fun, Args&& ...args) { fun(std::forward(args)...); } } // 3.1 contrained template with lambda ( typename std::enable_if>::value>::type foo(Fun fun) { fun(); } } // 3.2 contrained template with lambda (>=C++20) with concepts - great. // Produces very nice output when called with foo(3). namespace solution32 { template requires std::invocable void foo(Fun fun) { fun(); } // or template void foo2(Fun fun) { fun(); } // or void foo2(std::invocable auto fun) { fun(); } // Remark: // If you check the link for universal references, then you would know that this `fun` might // be accepted as `Fun&&` instead of `Fun`. } // 4. type erasure and std::function (>=C++11) // Remark: Advanced. See https://en.cppreference.com/w/cpp/utility/functional/function // and maybe https://www.youtube.com/watch?v=qn6OqefuH08. namespace solution4 { void foo(std::function fun) { fun(3, 3.14, 0); } } int main() { // Fails: See the comment there for "explanation". // solution2::foo(3); return 0; }