Function-like Entities

Function-like entities are things like function pointers, functors and lambdas. Like other entities, they can be passed around and used in interesting ways.

Function pointers are the first function-like entity. The syntax is pretty horrible when written out in full, fortunately we can use auto:

double add(double a, double b) {
    return a + b;
}

double (*p_func) (double double) = &add;
auto *p_func = &add;

We can pass them as function parameters (callbacks) to modify the behaviour of a function at runtime:

double calculate(double a, double b, double (*p_calculate) (double, double)) {
    return p_calculate(a, b);
}

You can use type aliases to simplify your code when using function pointers:

using add_doubles = double(*) (double, double);

I think this makes your code easier to read but harder to reason about as you have to go elsewhere to find the actual type.

Functors are the second type of function-like entities. They are classes that overload the () operator:

class SuperSecretEncryption {
public:
    char operator() {const char &c) {
        return static_cast<char>(c + 3);
    }
};

These can be passed in the same way as function pointers but unlike function pointers they have the advantage of holding state if needed.

Apart from their definition, the third type of function-like, lambdas, are modelled as functors. Everything that we can do with a functor, we can do with a lambda.

std::function in the functional library abstracts away the different types of function-like entity so we can store any kind in a collection or pass any kind to a function:

double calculate(double a, double b, std::function<double(double, double) calculate) {
    return calculate(a, b);
}

 

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.