Function Pointers & Lambdas

Function pointers are essential in C and C++ programming.

Function Pointers in C

#include <stdio.h>

// Function prototypes for the operations
int add(int a, int b) {
    return a + b;
}

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

int main() {
    // Define function pointers for the operations
    int (*operation)(int, int);

    int x = 10;
    int y = 5;
    int result;

    // Use the function pointer to point to the add function
    operation = add;
    result = operation(x, y);
    printf("Adding: %d + %d = %d\n", x, y, result);

    // Change the function pointer to point to the subtract function
    operation = subtract;
    result = operation(x, y);
    printf("Subtracting: %d - %d = %d\n", x, y, result);

    return 0;
}

We can make the code more intuitive by using a "typedef".

#include <stdio.h>

// Function prototypes for the operations
int add(int a, int b) {
    return a + b;
}

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

// Using typedef to simplify function pointer declarations
typedef int (*function_pointer_for_operation)(int, int);

int main() {
    // Declare a function pointer using the typedef
    function_pointer_for_operation operation;

    int x = 10;
    int y = 5;
    int result;

    // Use the function pointer to point to the add function
    operation = add;
    result = operation(x, y);
    printf("Adding: %d + %d = %d\n", x, y, result);

    // Change the function pointer to point to the subtract function
    operation = subtract;
    result = operation(x, y);
    printf("Subtracting: %d - %d = %d\n", x, y, result);

    return 0;
}

Function Pointers in C++

#include <iostream>
#include <functional>

// Function prototypes for the operations
int add(int a, int b) {
    return a + b;
}

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

int main() {
    // Using std::function to declare function pointers
    std::function<int(int, int)> operation;

    int x = 10;
    int y = 5;
    int result;

    // Assign the add function to the operation std::function
    operation = add;
    result = operation(x, y);
    std::cout << "Adding: " << x << " + " << y << " = " << result << std::endl;

    // Change the operation to subtract
    operation = subtract;
    result = operation(x, y);
    std::cout << "Subtracting: " << x << " - " << y << " = " << result << std::endl;

    return 0;
}

Similar to C, we can improve our code by using a typedef:

#include <iostream>
#include <functional>

// Define the function type using typedef for clarity and reusability
typedef std::function<int(int, int)> MathOperation;

// Function prototypes for the operations
int add(int a, int b) {
    return a + b;
}

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

int main() {
    // Declare a variable of type MathOperation
    MathOperation operation;

    int x = 10;
    int y = 5;
    int result;

    // Assign the add function to the operation
    operation = add;
    result = operation(x, y);
    std::cout << "Adding: " << x << " + " << y << " = " << result << std::endl;

    // Change the operation to subtract
    operation = subtract;
    result = operation(x, y);
    std::cout << "Subtracting: " << x << " - " << y << " = " << result << std::endl;

    return 0;
}

Example 1

#include <iostream>
#include <vector>
#include <algorithm>

// Comparison functions:

bool ascending_compare(int a, int b) {
    return a < b; // Change this to a > b for descending order
}
bool descending_compare(int a, int b) {
    return a > b; // Change this to a > b for descending order
}

int main() {
    // Create a vector of integers
    std::vector<int> vec = {-8, 5, 2, 9, 1, 5, 6, 3};

    // Sort the vector using the comparison function
    std::sort(vec.begin(), vec.end(), descending_compare);

    // Print the sorted vector
    std::cout << "Sorted vector: ";
    for (int value : vec) {
        std::cout << value << " ";
    }
    std::cout << std::endl;

    return 0;
}

Example 2

#include <iostream>
#include <chrono>
#include <functional>
#include <thread>

class Timer {
public:
    void callback_after_delay(std::function<void()> callback, int delay) {
        std::this_thread::sleep_for(std::chrono::milliseconds(delay));
        callback();
    }
};

void function_to_callback() {
  std::cout << "Callback invoked!" << std::endl;
}

int main() {
    Timer t;
    t.callback_after_delay(function_to_callback, 3000);

    return 0;
}

Lambda

Before we learn what is a lambda, let us consider naive code that achieves similar functionality of a lambda but it uses function pointer:

#include <algorithm>
#include <iostream>
#include <vector>

// A simple comparison function
bool compare(int a, int b) {
    return a < b;
}

int main() {
    std::vector<int> data = {5, 3, 9, 1, 6};

    // Sort using a function pointer
    std::sort(data.begin(), data.end(), compare);

    for (int n : data) {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    return 0;
}

In super naive terms, a lambda is a function pointer. Just remember this syntax: [] () {}

#include <algorithm>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> data = {5, 3, 9, 1, 6};

    // Sort using a lambda expression
    auto compare_function_lambda = [](int a, int b) {return a < b; };
    std::sort(data.begin(), data.end(), compare_function_lambda);

    for (int n : data) {
        std::cout << n << " ";
    }
    std::cout << std::endl;

    return 0;
}

 

 

Back to top