Saturday, January 11, 2014

Chapter:07 Lambda Expression

From the name 'lambda', we all remember our high school mathematics. I believe there must be a valid relation between these two, due to which the names are identical. If we read about 'lambda' on wikipedia we get the following:

"Lambda calculus  is a formal system in mathematical logic and computer science for expressing computation based on 'function' abstraction and application using variable 'binding' and 'substitution'".


This is precisely lambda function concept in C++11 does for us. These are also known as anonymous functions as these are not bind to a particular name. They can be  directly written at the place where we normally user/write 'functor' object.  I do not know what sort of benefits user would get if he uses lambda function instead of 'functor' object. Sometime we need to write a small 'functor' for which we need to write a class for that and inside that define 'operator()' which actually does the work for us.


These steps might be bit more for small 'functor' like functionality. In those cases we can use lambda function at the place where it would be used. Baring this I do not find any other advantages of lambda over 'functor' as 'functor' are one of the most optimized piece of code in entire STL. In fact they are easily inlined by compiler and hence they even do not have the cost of a function call. Anyway I think 'lambda' as another method over 'functor'  and we can interchange their usage with each other. As I have mentioned that  it is always good to know more than one method to address the same problem.
This kind of concepts supports this philosophy



The current program uses two lambda function. At first place we have written lambda function for the adding all members of a container. The key over here is syntax and I found it bit difficult to understand. However in simple scenario, if we want that lambda function return some output after it has executed for all  member of container, we should pass those variable inside '[ ]' body of lambda function. The main body would be inside the curly  braces and input argument would be passed inside '( )'. This is how it has been used in this program at both the places.


The second lambda function returns the number of elements which are less  than a particular value(3). Here we can see how we have passed two argument in the lambda. We should also notice that how code inside the lambda function has been written. It looks same as if we have written a function.



//Code Begins

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

void learn_lambda_expression(void) {
    std::vector<int> v_x{1,2,3,4,5};
    int sum{0};

    std::for_each(v_x.begin(), v_x.end(),
            [&sum](int x) { sum += x; return sum;});

    std::cout<<sum<<std::endl;

    std::vector<int> v_y{6,6,6,3,6,5,3};
    int count{0};
    int val{3};

    std::count_if(v_y.begin(), v_y.end(),
            [&count,&val](int x) {if(x == val) {++count; return true; }});

    std::cout<<count<<std::endl;
}

int main(int argc, const char* argv[]) {
    learn_lambda_expression();
    return 0;
}

//Code Ends



When I run the above program, I get the following output which was expected.



//Console Output Begins
$ ./test
15
2
//Console Output Ends



This is another example of where lambda function uses has been demonstrated. Here we want to store the elements which are less than a particular value(3) into another container. This lambda  function is similar to earlier one in our first example. Here  we have written the body for 'if' and 'else' part. At first part in the  program, we have defined a container of size same as the input container. Now 'copy if' STL algorithm would actually insert those members  which are greater than(3).


Once we are done with 'copy if' STL algorithm, we have the count of elements which are greater than (3). Now we can make use of that information and shrink our output vector to that much size. At last we have printed the output container members which stores the memebers which are greater than(3).




//Code Begins

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

void learn_lambda_expression(void) {
    std::vector<int> v_y{6,5,4,3,2,1,3,9};
    int val{3};
    std::vector<int> l_y(v_y.size());
    int count{0};

    std::copy_if(v_y.begin(), v_y.end(), l_y.begin(),
            [&val,&count](int x) {if(x > val)
            {++count; return true; }else {return false;}});

    l_y.resize(count);

    for(const auto& i: l_y)
        std::cout<<i<<"\t";
    std::cout<<std::endl;
}

int main(int argc, const char* argv[]) {
    learn_lambda_expression();
    return 0;
}

//Code Ends





When I run the above program, I get the following output.


//Console Output Begins
$ ./test
6    5    4    9   
//Console Output Ends


No comments:

Post a Comment