1. Recursive Lambda With std::function

Writing a recursive function is relatively straightforward: inside a function definition, you can call the same function by its name. How about lambdas?

int main() {
    auto factorial = [](int n) {
        return n > 1 ? n * factorial(n - 1) : 1;
    };
    return factorial(5);
}

This, unfortunately, doesn’t compile…

How can we fix this?

One way is to use std::function:

#include <functional>
int main() {
    const std::function<int(int)> factorial = [&factorial](int n) {
        return n > 1 ? n * factorial(n - 1) : 1;
    };
    return factorial(5);
}

This time, we need to capture factorial and then we can refer to it inside the lambda body.

And since C++14 we can also leverage generic lambdas and write the following code:

int main() {
    const auto factorial = [](int n) {
        const auto fact_impl = [](int n, const auto& impl) -> int {
            return n > 1 ? n * impl(n - 1, impl) : 1;
        };
        return fact_impl(n, fact_impl);
    };
    return factorial(5);
}

This time, it’s even more complicated (but doesn’t require heavy use of std::function). It uses internal lambda for the main computation and then it’s passed as a generic argument.

But I wonder: have you ever used recursive lambdas? Or, it’s better to rely on recursive functions (which seems to be far more comfortable to use and write).

2. constexpr Lambdas

But that’s not all with recursion… :)

Since C++17 we can write lambdas that have the call operator defined as constexpr. We can use this property and expand the recursive example into:

int main() {
    constexpr auto factorial = [](int n) {
        constexpr auto fact_impl = [](int n, const auto& impl) -> int {
            return n > 1 ? n * impl(n - 1, impl) : 1;
        };
        return fact_impl(n, fact_impl);
    };
    static_assert(factorial(5) == 120);
}

And in C++20, you can even apply consteval to mark lambdas which can be evaluated only at compile time.

#c++ #graphics #opengl #shaders #cplusplus #programming-c

5 Curious C++ Lambda Examples: Recursion, constexpr, Containers and More
3.50 GEEK