Function Pointer vs std::function in C++: Key Differences and Usage
function pointer is a simple pointer to a function with a fixed signature, offering fast calls but limited flexibility. std::function is a versatile wrapper that can hold any callable (functions, lambdas, functors) with type erasure, but with some runtime overhead.Quick Comparison
This table summarizes the main differences between function pointers and std::function in C++.
| Factor | Function Pointer | std::function |
|---|---|---|
| Type | Pointer to a function with fixed signature | Type-erased wrapper for any callable with matching signature |
| Flexibility | Can only point to free or static functions | Can store free functions, member functions (when bound), lambdas, functors |
| Performance | Very fast, minimal overhead | Some overhead due to type erasure and dynamic allocation |
| Memory | Small, just a pointer | Larger, may allocate memory dynamically |
| Usage Complexity | Simple syntax, but limited | More complex but more powerful |
| Copyability | Copying pointer is cheap | Copying may involve copying internal callable objects |
Key Differences
Function pointers are raw pointers that directly hold the address of a function with a specific signature. They are simple and efficient but limited to pointing only to free functions or static member functions. You cannot store lambdas with captures or member functions that require an object instance.
std::function is a template class that can hold any callable object matching a given signature. This includes free functions, lambdas (even with captures), functors (objects with operator()), and member functions when bound to an object. It uses type erasure internally to hide the actual callable type, which adds some runtime overhead and possible dynamic memory allocation.
While function pointers are faster and use less memory, std::function offers much more flexibility and ease of use in modern C++ code, especially when you need to store or pass around different types of callables uniformly.
Code Comparison
Here is an example using a function pointer to call a simple function.
#include <iostream> void greet() { std::cout << "Hello from function pointer!" << std::endl; } int main() { void (*funcPtr)() = &greet; // function pointer to greet funcPtr(); // call via function pointer return 0; }
std::function Equivalent
The same task using std::function allows more flexibility and can hold other callable types as well.
#include <iostream> #include <functional> void greet() { std::cout << "Hello from std::function!" << std::endl; } int main() { std::function<void()> func = greet; // std::function holding greet func(); // call via std::function // Also can hold a lambda std::function<void()> lambdaFunc = []() { std::cout << "Hello from lambda inside std::function!" << std::endl; }; lambdaFunc(); return 0; }
When to Use Which
Choose function pointers when you need the fastest possible calls and only need to point to simple free or static functions with a fixed signature. They are ideal for low-level or performance-critical code where flexibility is not required.
Choose std::function when you want flexibility to store any callable type, including lambdas with captures or functors, and when ease of use and code clarity matter more than minimal overhead. It is the modern C++ choice for callbacks, event handlers, and APIs that accept various callable types.