Passing a Function to a Function

Contents

Passing a Function to a Function#

Sometimes we want to write a function that takes another function as an argument. We’ll use this a lot when we learn about numerical methods, for instance, writing a function that computes an integral of a user-supplied function.

We use std::function (defined in the functional header) to define a function argument.

We need to give the signature of the function in the template arguments (< >). For instance, for our function:

double sum(double x, double y) {
    return x + y;
}

The function type is double(double, double) —it takes 2 double as arguments and returns a double. So we would use std::function<double(double, double)> f as a argument to define the function f, e.g.,

void f(std::function<double(double, double> f) {
    // do stuff with f ...
}

could be called as:

f(sum);

using our sum function defined above.

Example#

Here’s a concrete example—let’s write a function called fill that takes a vector x and a function f and returns a new vector creating by calling the function f on each value in x:

Listing 59 vector_fill.cpp#
#include <cmath>
#include <format>
#include <functional>
#include <iostream>
#include <numbers>
#include <vector>

std::vector<double> fill(const std::vector<double>& x,
                         std::function<double(double)> f) {

    std::vector<double> vec;
    for (auto e : x) {
        vec.push_back(f(e));
    }

    return vec;
}


double f_test(double x) {
    return std::sin(x);
}


int main() {

    std::vector<double> x{0.0,
                          std::numbers::pi / 4.0,
                          std::numbers::pi / 2.0,
                          3.0 * std::numbers::pi / 4.0,
                          std::numbers::pi};

    auto fvec = fill(x, f_test);

    for (std::size_t i = 0; i < fvec.size(); ++i) {
        std::cout << std::format("f({:.4f}) = {:.4f}\n", x[i], fvec[i]);
    }

}