Lambda Functions

Lambdas functions


C++11 provides the ability to create anonymous functions, called lambda functions. It allows a function to be defined at the point where it’s needed in another expression. It is a function that we can write inline in our code to pass in to another function. We can use lambdas wherever a function object or a functor is expected.

lambdas are more convenient than function objects because the tedium of writing boilerplate code for every function class (a constructor, data members and an overloaded operator() among the rest) is relegated to compiler.

A lambda expression has the form :

[capture] (parameters)->return-type {body}


The [] construct inside a function call’s argument list indicates the beginning of a lambda expression.

Capture Lists.
Unlike an ordinary function which can only access its parameters and local variables, a lambda function can also access variables from the enclosing scope.

There are two ways to capture variables with external references.

  • Capture by value
  • Capture by reference

Ways of Capturing.
  • [=]  //capture all of the variables from the enclosing scope by value
  • [&] //capture all of the variables from the enclosing scope by reference
  • [this] //capture all of the data members of the enclosing class
  • [=, &sum]: Captures any referenced variable within the lambda by value (making a copy), except sum that has to be captured by reference.
  • [&, divisor]: Captures any referenced variable within the lambda by reference, except divisor that has to be captured by value.
Suppose we want to count how many uppercase letters a string contains. Using for_each() to traverse a char array, the following lambda expression determines whether each letter is in uppercase. For every uppercase letter it finds, the lambda expression increments Uppercase, a variable defined outside the lambda expression.’

Int main()
{
            char s[]=”Hello World”;
            int Uppercase = 0; // Variable which will be modified by the lambda.
            for_each(s,s+sizeof(s),[&Uppercase](char c) {
if(isupper(c))
Uppercase++;
});
            cout<<”UpperCase Letters : ”<<Uppercase<<endl;
}

It’s as if you have defined a function whose body is placed inside another function call. The ampersand in [&Uppercase] means that the lambda body gets a reference to Uppercase so it can modify it. Without the ampersand, Uppercase would be passed by value.

Sample lambda function to print the container.

Int main()
{
            Vector<int> v = {1,2,3,4,5};
            For_each(v.begin(),v.end(),[](int n) {cout<<n<<endl;});
           
}

More examples :

Int main()
{
            // 1’st Lambda function
            cout<< [] (int a, int b) { return a*b; } (4,5) <<endl;

            // 2nd Lambda Function
            auto f = [] (int a, int b) {return a*b ; };
            cout<<f(4,5);

            // Explicitly specify the return type of a lambda function.
            cout <<[] (int a)->int { return n*n;  } (5) ;

}

Output:
g++  -std=c++11 lambda.cpp
20



20


Closures

  • A lambda object that holds captured values is also called a closure
  • The runtime effect of a lambda expression is the generation of an object. Such objects are known as closures.



Comments

Popular posts from this blog

C++ Guidelines for Multithreaded System

Signalling System #7(SS7) Protocol.

std::shared_ptr