0
0
CppComparisonIntermediate · 4 min read

Function Pointer vs std::function in C++: Key Differences and Usage

In C++, a 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++.

FactorFunction Pointerstd::function
TypePointer to a function with fixed signatureType-erased wrapper for any callable with matching signature
FlexibilityCan only point to free or static functionsCan store free functions, member functions (when bound), lambdas, functors
PerformanceVery fast, minimal overheadSome overhead due to type erasure and dynamic allocation
MemorySmall, just a pointerLarger, may allocate memory dynamically
Usage ComplexitySimple syntax, but limitedMore complex but more powerful
CopyabilityCopying pointer is cheapCopying 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.

cpp
#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;
}
Output
Hello from function pointer!
↔️

std::function Equivalent

The same task using std::function allows more flexibility and can hold other callable types as well.

cpp
#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;
}
Output
Hello from std::function! Hello from lambda inside std::function!
🎯

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.

Key Takeaways

Function pointers are simple, fast, and limited to free or static functions with fixed signatures.
std::function can hold any callable matching a signature, including lambdas and functors, with some overhead.
Use function pointers for performance-critical, simple cases; use std::function for flexibility and modern C++ style.
std::function adds runtime overhead due to type erasure and possible dynamic memory allocation.
std::function improves code readability and supports more use cases than raw function pointers.