Skip to content
  • Function Pointers, Functors & std::function · C++

Function Pointers, Functors & std::function

LearnViaNotes @learnvianotes· 3 min read

Three ways to treat “a function” as a value: raw function pointers (C-style), function objects (classes with operator()), and the type-erased std::function wrapper.

Function pointers

C++
#include <iostream>

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }

int apply(int (*op)(int, int), int x, int y) { return op(x, y); }

using BinaryOp = int (*)(int, int);          // alias makes the syntax readable

int main() {
    BinaryOp ops[] = {add, mul};             // table of functions
    for (BinaryOp op : ops) std::cout << apply(op, 3, 4) << ' ';
    std::cout << '\n';
    int (*p)(int, int) = &add;               // & and * are optional for functions
    std::cout << (*p)(1, 1) << ' ' << p(2, 2) << '\n';
}
Output
7 12
2 4

Functors (function objects)

C++
#include <algorithm>
#include <iostream>
#include <vector>

class InRange {                               // a functor can carry state
    int lo_, hi_;
public:
    InRange(int lo, int hi) : lo_(lo), hi_(hi) {}
    bool operator()(int x) const { return lo_ <= x && x <= hi_; }
};

int main() {
    std::vector<int> v{1, 5, 9, 12, 7};
    std::cout << std::count_if(v.begin(), v.end(), InRange(5, 10)) << '\n';
    std::sort(v.begin(), v.end(), std::greater<int>());   // standard functor from <functional>
    std::cout << v.front() << '\n';
}
Output
3
12

std::function

std::function<R(Args...)> can hold any callable with that signature — function pointer, functor or lambda (even with captures). It's the tool for storing callbacks of unknown type, at the cost of a possible heap allocation and an indirect call.

C++
#include <functional>
#include <iostream>
#include <map>
#include <string>

int sub(int a, int b) { return a - b; }

int main() {
    int bonus = 100;
    std::map<std::string, std::function<int(int, int)>> calc{
        {"+", [](int a, int b) { return a + b; }},
        {"-", sub},
        {"max", [](int a, int b) { return std::max(a, b); }},
        {"bonus", [bonus](int a, int) { return a + bonus; }},
    };
    for (const auto& [name, fn] : calc) std::cout << name << ' ' << fn(8, 3) << '\n';

    std::function<void()> empty;
    std::cout << std::boolalpha << static_cast<bool>(empty) << '\n';   // calling it would throw bad_function_call
}
Output
+ 11
- 5
bonus 108
max 8
false

std::bind and std::invoke

C++
#include <functional>
#include <iostream>

int power(int base, int exp) { int r = 1; while (exp--) r *= base; return r; }
struct Account { int balance = 50; int get() const { return balance; } };

int main() {
    using namespace std::placeholders;
    auto square = std::bind(power, _1, 2);           // fix the second argument
    auto squareL = [](int b) { return power(b, 2); }; // the lambda equivalent (preferred)
    std::cout << square(7) << ' ' << squareL(7) << '\n';

    Account acc;
    std::cout << std::invoke(&Account::get, acc) << ' ' << std::invoke(power, 2, 5) << '\n';  // uniform call syntax
}
Output
49 49
50 32
OptionOverheadHolds state?Use when
Function pointerIndirect callNoC APIs, simple tables of functions
Lambda / functor + template parameterNone (inlined)YesAlgorithms, hot paths: template <class F> void run(F f)
std::functionType erasure; maybe allocationYesStoring heterogeneous callbacks (maps, members, event handlers)

Why is std::sort with a lambda often faster than C's qsort?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report