C++ Lambda Expressions

Introduction

Lambda expressions, or lambdas for short, are the so-called: anonymous function objects.

Lambda expressions are anonymous function objects.

They allow us to write a short code snippet to be used as a standard-library function predicate.

Lambdas have a capture list, marked by [ ] where we can capture local variables by reference or copy, parameter list with optional parameters marked with ( ), and a lambda body, marked with { }.

An empty lambda looks like [] () {};.

A simple example of counting only the even numbers in a set using the lambda as a predicate:

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

int main() //  w w w . j a v a  2 s  .  c om
{ 
    std::vector<int> v = { 1, 2, 3, 4, 5 }; 
    auto counteven = std::count_if(std::begin(v), std::end(v), 
        [](int x) {return x % 2 == 0; }); // lambda expression 
    std::cout << "The number of even vector elements is: " << counteven; 
} 

Function object

A function object, or a functor , is an object of a class that can be called as a function.

To be able to call an object like a function, we must overload the function call operator () for our class:

#include <iostream> 

class MyClass /*from  w w  w.  j  a v  a2s.c  o m*/
{ 
public: 
    void operator()() 
    { 
        std::cout << "Function object called." << '\n'; 
    } 
}; 

int main() 
{ 
    MyClass myobject; 
    myobject(); // invoke the function object 
} 

The function object can have one or more parameters; in this case, there is one parameter called x:

#include <iostream> 

class MyClass /*from w  ww .ja v  a 2s . c  o m*/
{ 
public: 
    void operator()(int x) 
    { 
         std::cout << "Function object with a parameter " << x << " called."; 
    } 
}; 

int main() 
{ 
    MyClass myobject; 
    myobject(123); // invoke the function object 
} 

The function object can also return a value.

For example, the following function object checks if the parameter is even number:

#include <iostream> 

class MyClass //from ww w.  j a  v  a  2  s .  co  m
{ 
public: 
    bool operator()(int x) 
    { 
        if (x % 2 == 0) 
        { 
            return true; 
        } 
        else 
        { 
            return false; 
        } 
    } 
}; 
int main() 
{ 
    MyClass myobject; 
    bool isEven = myobject(123); 
    if (isEven) 
    { 
        std::cout << "The number is even." << '\n'; 
    } 
    else 
    { 
        std::cout << "The number is odd." << '\n'; 
    } 
} 

It is said that function objects carry their values.

Since they are objects of a class, they can have data members they carry with them.

This separates them from regular functions.

As we can see, overloading operator () and writing the entire class can be somewhat cumbersome if all we want is a simple function object.

That is where the lambda expressions come into play.

Lambda expressions

Lambda expressions are anonymous/unnamed function objects.

Lambda expression signature is:

[captures](parameters){lambda_body}; 

To define and invoke a simple lambda, we use:

#include <iostream> 

int main() /*from w w w . j  ava2 s .  c  o  m*/
{ 
    auto mylambda = []() {std::cout << "Hello from a lambda"; }; 
    mylambda(); 
} 

Here, we assign the result of a lambda expression: []() {std::cout << "Hello from a lambda"; } to a variable mylambda.

Then we invoke this lambda by using the function call operator ().

Since lambdas are unnamed functions, here we gave it the name of mylambda, to be able to invoke the code from the lambda expression itself.




PreviousNext

Related