Callback keyword and Pass a function as an argument in C++
2024-09-10 , 4 mins read.
We will walk through the concepts of callbacks and passing functions as arguments in C++.
1. What is a "Callback"?
A callback is a function that you pass as an argument to another function, and that function can call (or "invoke") the passed-in function at some point. It's like saying, "I'll pass you this function, and you call it when you need it."
In C++, callbacks are usually implemented using function pointers or, more commonly in modern C++, using std::function and lambdas (anonymous functions).
2. How to Pass a Function as an Argument in C++?
In C++, you can pass functions as arguments using the following techniques:
Function Pointers (classic C++ approach)
std::function(modern C++ approach, introduced in C++11)Lambdas (anonymous inline functions, introduced in C++11)
Example of Using Function Pointers:
If you have a function myFunction that you want to pass to another function, you can use function pointers.
// Define a function
void myFunction(int x) {
std::cout << "Called with: " << x << std::endl;
}
// Function that takes a function pointer as an argument
void callWithArgument(void (*callback)(int), int value) {
// Call the function passed as the callback
callback(value);
}
int main() {
// Pass myFunction as a function pointer
callWithArgument(myFunction, 42);
}Output:
Called with: 42Example of Using std::function and Lambdas:
In modern C++, std::function is used to pass functions as arguments, and lambdas are inline anonymous functions that can be passed to std::function.
Here’s an example using both:
#include <iostream>
#include <functional> // For std::function
// A function that takes a std::function (callback) as an argument
void callWithCallback(std::function<void(int)> callback, int value) {
// Call the function passed as the callback
callback(value);
}
int main() {
// Lambda function that can be passed as a callback
auto lambda = [](int x) {
std::cout << "Lambda called with: " << x << std::endl;
};
// Call with lambda as the callback
callWithCallback(lambda, 42);
// You can also pass a regular function
callWithCallback([](int x) { std::cout << "Inline Lambda called with: " << x << std::endl; }, 10);
}Output:
Lambda called with: 42
Inline Lambda called with: 103. How to Use a Function as an Argument in C++?
When you want to pass a function as an argument, the function you pass could either be:
A regular function
A lambda function
A function pointer
A
std::functiontype, which can hold a variety of callable objects (including lambdas, function pointers, and more)
In KVDB project, we use std::function<void(const KeyValue&)> in the inOrderTraversal function, passing a function (or lambda) that takes a KeyValue and returns void.
Here's an example using std::function in a tree traversal:
Using std::function in Tree Traversal
std::function in Tree Traversal#include <functional> // For std::function
#include <iostream>
// Simplified KeyValue structure
struct KeyValue {
int key;
int value;
KeyValue(int k, int v) : key(k), value(v) {}
bool operator>=(const KeyValue& other) const { return key >= other.key; }
bool operator<=(const KeyValue& other) const { return key <= other.key; }
...
...
};
// Simplified RedBlackTree class with an inOrderTraversal method
class RedBlackTree {
public:
struct TreeNode {
KeyValue keyValue;
TreeNode* left;
TreeNode* right;
TreeNode(KeyValue kv) : keyValue(kv), left(nullptr), right(nullptr) {}
};
RedBlackTree() : root(nullptr) {}
// Insert for demonstration (simplified, non-balanced insertion)
void insert(KeyValue kv) {
root = insertRec(root, kv);
}
// Inorder traversal with callback (using std::function)
void inOrderTraversal(std::function<void(const KeyValue&)> callback) const {
inOrderTraversal(root, callback);
}
private:
TreeNode* root;
TreeNode* insertRec(TreeNode* node, KeyValue kv) {
if (!node) return new TreeNode(kv);
if (kv.key < node->keyValue.key) node->left = insertRec(node->left, kv);
else node->right = insertRec(node->right, kv);
return node;
}
void inOrderTraversal(TreeNode* node, std::function<void(const KeyValue&)> callback) const {
if (node == nullptr) return;
inOrderTraversal(node->left, callback); // Visit left subtree
callback(node->keyValue); // Apply callback to current node
inOrderTraversal(node->right, callback); // Visit right subtree
}
};
int main() {
RedBlackTree tree;
tree.insert(KeyValue(10, 100));
tree.insert(KeyValue(5, 50));
tree.insert(KeyValue(20, 200));
// Use inOrderTraversal with a lambda callback
tree.inOrderTraversal([](const KeyValue& kv) {
std::cout << "Key: " << kv.key << ", Value: " << kv.value << std::endl;
});
return 0;
}Output:
Key: 5, Value: 50
Key: 10, Value: 100
Key: 20, Value: 200Explanation:
Lambda Functions: The
inOrderTraversalfunction accepts a lambda as a callback. This lambda processes each key-value pair during the traversal.std::function:std::function<void(const KeyValue&)>is used to define the type of the callback function, which takes aKeyValueas an argument and returnsvoid.
Summary:
Callback refers to a function passed as an argument to another function, which is called ("invoked") within the receiving function.
You can pass functions as arguments using function pointers or
std::function(the modern approach).Lambdas are a convenient way to define inline, anonymous functions and pass them as arguments.
Last updated