C++: Pass Function as Parameter

In C++, functions can be passed as parameters to other functions. This is used for implementing callbacks or when designing algorithms that require dynamic behaviour.

In this tutorial, we will learn different ways to pass functions as parameters to other functions, with examples.


Ways to Pass Functions as Parameters

There are many ways in which you can pass function as a parameter to another function. In this tutorial, we will discuss the two most common ways to pass functions as parameters in C++:

  1. Using function pointers
  2. Using std::function and lambda expressions

Method 1 – Pass Functions as Parameters using Function Pointers

A function pointer stores the address of a function and can be passed as a parameter to another function.

Syntax

</>
Copy
return_type (*function_pointer_name)(parameter_list)
return_type
Specifies the data type of the value that the function returns. For example, int if the function returns an integer, void if it returns nothing, etc.
*function_pointer_name
*function_pointer_name defines the name of the function pointer. The asterisk (*) indicates that it is a pointer.
parameter_list
Specifies the types and names of the parameters that the function accepts. This must match the parameter list of the function the pointer will point to. For example, (int a, int b) indicates the function takes two integer parameters.

Example

In this example, we define a function compute() that accepts the function pointer as a parameter.

Program – main.cpp

</>
Copy
#include <iostream>
using namespace std;

// Function to be passed as a parameter
int multiply(int a, int b) {
    return a * b;
}

// Function that accepts a function pointer as a parameter
int compute(int x, int y, int (*operation)(int, int)) {
    return operation(x, y);
}

int main() {
    int result = compute(5, 4, multiply);
    cout << "Result: " << result << endl; // Output: Result: 20
    return 0;
}

Explanation

  1. multiply: A simple function that takes two integers and returns their product.
  2. compute: A higher-order function that accepts two integers and a function pointer as parameters.
  3. The main function passes the multiply function as an argument to compute.

Method 2 – Pass Functions as Parameters using std::function and Lambda Expressions

std::function is a standard library feature that can store any callable object, including function pointers, lambdas, and objects with overloaded operator().

Example

In this example, we define a function compute() that accepts a callable object as a parameter.

Program – main.cpp

</>
Copy
#include <iostream>
#include <functional>
using namespace std;

// Function to be used
int subtract(int a, int b) {
    return a - b;
}

// Function that accepts std::function as a parameter
int compute(int x, int y, std::function<int(int, int)> operation) {
    return operation(x, y);
}

int main() {
    // Using a regular function
    cout << "Subtraction: " << compute(10, 3, subtract) << endl;

    // Using a lambda expression
    cout << "Addition: " << compute(10, 3, [](int a, int b) {
        return a + b;
    }) << endl;

    return 0;
}

Output

Subtraction: 7
Addition: 13

Explanation

  1. std::function<int(int, int)>: Specifies a callable object that takes two integers and returns an integer.
  2. compute: A higher-order function that accepts a callable object as a parameter.
  3. The main function demonstrates passing both a regular function and a lambda expression.

Advantages of Using std::function

  • Flexibility: Can accept functions, lambdas, and callable objects.
  • Type Safety: Ensures the passed callable object matches the expected signature.
  • Readability: Makes it clear that the function is designed to accept custom behaviors.

Comparison between Function Pointers and std::function

AspectFunction Pointersstd::function
FlexibilityOnly works with functions.Can work with functions, lambdas, and callable objects.
Type SafetyLess type-safe and requires careful handling.More type-safe and easier to use with templates.
OverheadMinimal overhead.Slightly higher overhead due to type erasure.

Best Practices to Pass Function as a Parameter

  1. Use function pointers for simple scenarios where performance is critical.
  2. Use std::function for more flexible and type-safe code.
  3. Leverage lambda expressions for inline functions and reducing boilerplate code.