Export (0) Print
Expand All

Examples of Lambda Expressions

This topic contains examples of how to use lambda expressions in your programs. For an overview of lambda expressions, see Lambda Expressions in C++. For more information about the structure of a lambda expression, see Lambda Expression Syntax.

Description

Because a lambda expression is typed, you can assign it to an auto variable or to a function object, as shown in the following example:

Code

// declaring_lambda_expressions1.cpp
#include <functional>

int main()
{
   // Assign the lambda expression that adds two numbers to an auto variable.
   auto f1 = [] (int x, int y) { return x + y; }; 

   // Assign the same lambda expression to a function object.
   function<int (int, int)> f2 = [] (int x, int y) { return x + y; };
}

Comments

For more information about the auto keyword, see auto Keyword (Type Deduction). For more information about the function class, see function Class.

Although lambda expressions are most often declared in the body of a method or function, you can declare them anywhere that you can initialize a variable.

Description

The Visual C++ compiler binds a lambda expression to its captured variables when the expression is declared instead of when the expression is called. The following example shows a lambda expression that captures the local variable i by value and the local variable j by reference. Because the lambda expression captures i by value, the reassignment of i later in the program does not affect the result of the expression. However, because the lambda expression captures j by reference, the reassignment of j does affect the result of the expression.

Code

// declaring_lambda_expressions2.cpp
// compile with: /EHsc
#include <iostream>
#include <functional>

int main()
{
   using namespace std;

   int i = 3;
   int j = 5;

   // The following lambda expression captures i by value and
   // j by reference.
   function<int (void)> f = [i, &j] { return i + j; };

   // Change the values of i and j.
   i = 22;
   j = 44;

   // Call f and print its result.
   cout << f() << endl;
}

Output

47

Comments

You can call a lambda expression directly or pass it as an argument to Standard Template Library (STL) algorithms such as find_if.

Description

The following example declares a lambda expression that returns the sum of two integers and calls the expression immediately with the arguments 5 and 4:

Code

// calling_lambda_expressions1.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;
   int n = [] (int x, int y) { return x + y; }(5, 4);
   cout << n << endl;
}

Output

9

Description

The following example passes a lambda expression as an argument to the find_if function. The lambda expression returns true if its parameter is an even number.

Code

// calling_lambda_expressions2.cpp
// compile with: /EHsc
#include <list>
#include <algorithm>
#include <iostream>

int main()
{
   using namespace std;

   // Create a list of integers with a few initial elements.
   list<int> numbers;
   numbers.push_back(13);
   numbers.push_back(17);
   numbers.push_back(42);
   numbers.push_back(46);
   numbers.push_back(99);

   // Use the find_if function and a lambda expression to find the 
   // first even number in the list.
   const list<int>::const_iterator result =
      find_if(numbers.begin(), numbers.end(),
         [](int n) { return (n % 2) == 0; });

   // Print the result.
   if (result != numbers.end())
   {
       cout << "The first even number in the list is " 
            << (*result) 
            << "." 
            << endl;
   }
   else
   {
       cout << "The list contains no even numbers." 
            << endl;
   }
}

Output

The first even number in the list is 42.

Comments

For more information about the find_if function, see find_if. For more information about the STL functions that perform algorithms, see <algorithm>.

Description

You can invoke a lambda expression that is assigned to a variable by using the function-call operator, operator(). The following example assigns a lambda expression to an auto variable and then uses the function-call operator to invoke the lambda expression:

Code

// calling_lambda_expressions3.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;

   // Assign the lambda expression that adds two numbers to an 
   // auto variable.
   auto f = [] (int x, int y) { return x + y; };

   // Invoke the function object and print its result.
   cout << f(21, 12) << endl;
}

Output

33

Comments

For more information about the function call operator, see Function Call (C++).

[go to top]

Description

You can nest a lambda expression inside another. The following example shows a lambda expression that contains another lambda expression. The inner lambda expression multiplies its argument by 2 and returns the result. The outer lambda expression calls the inner lambda expression with its argument and adds 3 to the result.

Code

// nesting_lambda_expressions.cpp
// compile with: /EHsc
#include <iostream>

int main()
{
   using namespace std;

   // The following lambda expression contains a nested lambda
   // expression.
   int m = [](int x) 
      { return [](int y) { return y * 2; }(x) + 3; }(5);

   // Print the result.
   cout << m << endl;
}

Output

13

Comments

In this example, [](int y) { return y * 2; } is the nested lambda expression.

[go to top]

Description

Many programming languages support the concept of a higher-order function. A higher-order function is a lambda expression that takes another lambda expression as its argument or that returns a lambda expression. You can use the function class to allow for a C++ lambda expression to behave like a higher-order function. The following example shows a lambda expression that returns a function object and a lambda expression that takes a function object as its argument:

Code

// higher_order_lambda_expression.cpp
// compile with: /EHsc
#include <iostream>
#include <functional>

int main()
{
   using namespace std;

   // The following code declares a lambda expression that returns 
   // another lambda expression that adds two numbers. 
   // The returned lambda expression captures parameter x by value.
   auto g = [](int x) -> function<int (int)> 
      { return [=](int y) { return x + y; }; };

   // The following code declares a lambda expression that takes another
   // lambda expression as its argument.
   // The lambda expression applies the argument z to the function f
   // and adds 1.
   auto h = [](const function<int (int)>& f, int z) 
      { return f(z) + 1; };

   // Call the lambda expression that is bound to h. 
   auto a = h(g(7), 8);

   // Print the result.
   cout << a << endl;
}

Output

16

Comments

Description

You can use lambda expressions in the body of a method. The lambda expression can access any method or data member that the enclosing method can access. You can explicitly or implicitly capture the this pointer to provide access to methods and data members of the enclosing class.

The following example shows the Scale class, which encapsulates a scale value. The ApplyScale method uses a lambda expression to print the product of each element in a vector object and the scale value. The lambda expression explicitly captures the this pointer so that it can access the _scale member.

// method_lambda_expression.cpp
// compile with: /EHsc
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

class Scale
{
public:
   // The constructor.
   explicit Scale(int scale)
      : _scale(scale)
   {
   }

   // Prints the product of each element in a vector object 
   // and the scale value to the console.
   void ApplyScale(const vector<int>& v) const
   {
      for_each(v.begin(), v.end(), 
         [this](int n) { cout << n * _scale << endl; });
   }

private:
   int _scale;
};

int main()
{
   vector<int> values;
   values.push_back(3);
   values.push_back(6);
   values.push_back(9);

   // Create a Scale object that scales elements by 3 and apply
   // it to the vector object.
   Scale s(3);
   s.ApplyScale(values);
}

Output

9
18
27

Comments

You can use the this pointer explicitly in a method, as shown in the following example:

void ApplyScale(const vector<int>& v) const
{
   for_each(v.begin(), v.end(), 
      [this](int n) { cout << n * this->_scale << endl; });
}

You can also capture the this pointer implicitly, as shown in the following example:

void ApplyScale(const vector<int>& v) const
{
   for_each(v.begin(), v.end(), 
      [=](int n) { cout << n * _scale << endl; });
}

[go to top]

Description

Because lambda expressions are typed, you can use them with C++ templates. The following example shows the negate_all and print_all functions. The negate_all function applies the unary operator- to each element in the vector object. The print_all function prints each element in the vector object to the console.

Code

// template_lambda_expression.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <iostream>

using namespace std;

// Negates each element in the vector object.
template <typename T> 
void negate_all(vector<T>& v)
{
    for_each(v.begin(), v.end(), [] (T& n) { n = -n; } );
}

// Prints to the console each element in the vector object.
template <typename T> 
void print_all(const vector<T>& v)
{
   for_each(v.begin(), v.end(), [] (const T& n) { cout << n << endl; } );
}

int main()
{
   // Create a vector of integers with a few initial elements.
   vector<int> v;
   v.push_back(34);
   v.push_back(-43);
   v.push_back(56);

   // Negate each element in the vector.
   negate_all(v);

   // Print each element in the vector.
   print_all(v);
}

Output

-34
43
-56

Comments

For more information about C++ templates, see Templates.

[go to top]

Description

The body of a lambda expression follows the rules for both structured exception handling (SEH) and C++ exception handling. You can handle a raised exception in the body of a lambda expression or defer exception handling to the enclosing scope. The following example uses the for_each function and a lambda expression to fill one vector object with the values of another. It uses a try/catch block to handle invalid access to the first vector.

Code

// eh_lambda_expression.cpp
// compile with: /EHsc
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

int main()
{
   // Create a vector that contains 3 elements.
   vector<int> elements(3);

   // Create another vector that contains index values.
   vector<int> indices(3);
   indices[0] = 0;
   indices[1] = -1; // This is not a subscript. It will trigger the exception.
   indices[2] = 2;

   // Use the values from the vector of index values to 
   // fill the elements vector. This example uses a 
   // try/catch block to handle invalid access to the 
   // elements vector.
   try
   {
       for_each(indices.begin(), indices.end(), 
           [&] (int index) { elements.at(index) = index; });
   }
   catch (const out_of_range& e) 
   {
       cerr << "Caught '" << e.what() << "'." << endl;
   };
}

Output

Caught 'invalid vector<T> subscript'.

Comments

For more information about exception handling, see Exception Handling in Visual C++.

[go to top]

Description

The capture clause of a lambda expression cannot contain a variable with a managed type. However, you can pass an argument with a managed type to the parameter list of a lambda expression. The following example contains a lambda expression that captures the local unmanaged variable ch by value and takes a System.String object as its parameter:

Code

// managed_lambda_expression.cpp
// compile with: /clr
using namespace System;

int main()
{
    char ch = '!'; // a local unmanaged variable
    
    // The following lambda expression captures local variables
    // by value and takes a managed String object as its parameter.
    [=] (String ^s) 
        { Console::WriteLine(s + Convert::ToChar(ch)); }("Hello");
}

Output

Hello!

Comments

You can use also lambda expressions with the STL/CLR library. For more information about STL/CLR, see STL/CLR Library Reference.

[go to top]

Community Additions

ADD
Show:
© 2014 Microsoft