Pages

Lambda for Fibonacci

I have found out an interesting example on an MSDN page that shows some lambda expression features.

I have reworked it a bit, and here you have the result:

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

namespace
{
    void dump(const std::vector< v)
    {
        std::for_each(v.begin(), v.end(), [](int n) { std::cout << n << ' '; }); // 1
        std::cout << std::endl;
    }
}

void fibonacci(size_t size)
{
    std::vector<int> vec(size, 1); // 2
    dump(vec);

    int base = 0; // 3 
    std::generate_n(vec.begin() + 2, size - 2, // 4
        [base, <vec]() mutable throw() -> int // 5
        {
            return vec[base++] + vec[base]; // 6
        });

    dump(vec);
    std::cout << base << std::endl; // 7
}
1. The first usage of a lambda expression here is not much interesting, it helps the for_each construct to output the vector elements to the console. The currently scanned element is assigned to the lambda parameter that is then used in the lambda body.
2. This vector is created using the size passed by the user, and initializing each of its values to one. Performance-wise this is not an optimal solution, but we can leave with it in this context.
3. in the variable base we keep the index of the first element in the vector that we need to get to calculate the next fibonacci value.
4. The generate_n() STL algorithm operates on a sequence, starting from the element pointed by the iterator passed as first parameter, iterating for the number of times passed as second parameter, applying the predicate specified as third parameter. It is here that we have an interesting lambda expression.
5. In the introduction clause we see the base variable passed by value, and the vec by reference. These variables will be accessible in the lambda body. The "mutable" specification means basically that the function local variable are copied to the lambda expression, so no change done there affect the original ones. The "throw()" clause tells that we are not supposed to throw any exception in the lambda expression. The "arrow" is actually the return type clause, in this case specifying that the lambda expression returns an int, in this case it is not mandatory, the compiler is smart enough to find out which type is the return value.
6. Notice that "base" is increased, this is the reason why we must specify this lambda expression as "mutable". By default you can't do that on a lambda by value parameter.
7. Here we'll see that the local "base" has not been changed.

No comments:

Post a Comment