Passing a Function as a Parameter in C++

Last Updated : 14 Jul, 2026

Passing a function as an argument allows a program to change behavior dynamically at runtime. Such a function is called a callback and is commonly used to customize operations like sorting, searching, and event handling.

  • Callbacks make code reusable and flexible by passing behavior as an argument.
  • Modern C++ also supports callbacks using function wrappers (such as std::function).
C++
#include <iostream>
using namespace std;

// Callback function
int square(int x) {
    return x * x;
}

// Function that takes another function as parameter
void process(int value, int (*func)(int)) {
    cout << "Result: " << func(value);
}

int main() {
    process(5, square);   // Passing function as argument
    return 0;
}

Output
Result: 25

Explanation

  • "square()" is a normal function that performs a task.
  • "process()" receives another function as a parameter.
  • square is passed as a callback and executed inside "process()"

Syntax

A function can also be passed to another function by passing its address to that function, In simple terms, it could be achieved via pointers.

return_type (*pointer_name)(prm1, prm2)

  • return_type: data type of the value that the function returns.
  • pointer_name: Name of the function pointer.
  • prm1, prm2: Parameters that function accepts.

Ways to Pass Functions in C++

Functions can be passed in multiple ways depending on the use case.

1. Passing a Function Pointer

C++
#include <iostream>
using namespace std;

int add(int x, int y) { return x + y; }

int mul(int x, int y) { return x * y; }

// Function invoke takes a 
// pointer to the function
int invoke(int x, int y, int 
            (*f)(int, int)) {
    return f(x, y);
}

int main() {
  
    // Pass address of add & mul
    // function 
    cout << invoke(20, 10, &add) << '\n';
    cout << invoke(20, 10, &mul);

    return 0;
}

Output
30
200

Explanation

  • invoke() accepts a function pointer.
  • The address of either add() or mul() is passed.
  • The same function executes different logic depending on the callback supplied.

2. Using std::function

Since C++11, the Standard Library provides std::function, which can store any callable object.

Syntax

function< rtype_type (prm1, prm2)> function_name

C++
#include <bits/stdc++.h>
using namespace std;

int add(int x, int y) { return x + y; }
int mul(int x, int y) { return x * y; }

// Function that takes 
// function as argument
int invoke(int x, int y, 
           function<int(int, int)> f) {
    return f(x, y);
} 


int main() {
  
    // Pass address of add & mul
    // function 
    cout << invoke(20, 10, &add) << '\n';
    cout << invoke(20, 10, &mul);
    return 0;
}

Output
30
200

Explanation

  • std::function wraps callable objects.
  • It can accept normal functions, lambdas, functors, and bound member functions.
  • It provides greater flexibility than raw function pointers.

3. Using Lambda Expressions

Lambda expressions provide inline anonymous functions that can be passed directly as arguments.

C++
#include <functional>
#include <iostream>
using namespace std;

// Function that takes a pointer
// to a function
int invoke(int x, int y,
           function<int(int, int)> func) {
    return func(x, y);
}

int main() {

    // Define lambdas for addition 
    // operation and another
    // function as a parameter
    int k = invoke(20, 10,
                   [](int x,
                      int y) -> int {
                      return x + y;
                   });
    cout << k;
    return 0;
}

Output
30

Explanation

  • The lambda performs addition.
  • It is passed directly without creating a separate function.
  • This keeps callback code short and readable.

4. Passing Member Functions

Both static and non-static member functions can be used as callbacks.

  • Static member functions behave like normal functions.
  • Non-static member functions require an object and are usually passed using std::bind or a lambda.
C++
#include <bits/stdc++.h>
using namespace std;

class C {
public:
    int f(int a, int b) {
        return a * b;
    }
};

void invoke(function<int(int, int)> calc) {
    
  	// Call the member function 
  	// using function
  	cout << calc(10, 20);
}

int main() {
    C c;
    
    // Wrapping member function of C
    auto calc = bind(&C::f, &c, 
                placeholders::_1,
                placeholders::_2);
    
    // Passing it as argument
  	invoke(calc);
    return 0;
}

Output
200

Explanation

  • bind() associates the member function with object c.
  • The returned callable object behaves like a normal function.
  • nvoke() calls the bound function and prints the result.

Best Practices

Follow these practices while passing functions as parameters:

  • Prefer std::function when different callable objects must be supported.
  • Use lambda expressions for short, one-time callbacks.
  • Use function pointers for lightweight callbacks when flexibility is unnecessary.
  • Avoid unnecessary use of std::bind; lambdas are often simpler and easier to read.

Function Pointers vs std::function

FeatureFunction Pointerstd::function
Type SafetyNot type-safe. Type must match exactly between declaration and usage.Type-safe; ensures correct signature of callable objects.
FlexibilityLess flexible. Only supports function pointers.More flexible. Supports function pointers, lambdas, and functors.
DeclarationRequires explicit declaration of function signature.Easier to use; can wrap any callable type.
Memory ManagementNo built-in memory management.Manages memory automatically, including capturing lambdas.
Storing StateCannot store state.Can store state in addition to functions (e.g., lambdas or functors with state).
Use CaseSimple function calls and callbacks.When you need to store, pass, or return any callable object.
Comment