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++:
- Using function pointers
- 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
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
#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
multiply
: A simple function that takes two integers and returns their product.compute
: A higher-order function that accepts two integers and a function pointer as parameters.- The
main
function passes themultiply
function as an argument tocompute
.
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
#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
std::function<int(int, int)>
: Specifies a callable object that takes two integers and returns an integer.compute
: A higher-order function that accepts a callable object as a parameter.- 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
Aspect | Function Pointers | std::function |
---|---|---|
Flexibility | Only works with functions. | Can work with functions, lambdas, and callable objects. |
Type Safety | Less type-safe and requires careful handling. | More type-safe and easier to use with templates. |
Overhead | Minimal overhead. | Slightly higher overhead due to type erasure. |
Best Practices to Pass Function as a Parameter
- Use function pointers for simple scenarios where performance is critical.
- Use
std::function
for more flexible and type-safe code. - Leverage lambda expressions for inline functions and reducing boilerplate code.