Example to explain the use of lambda expressions in C + + programming _c language

Source: Internet
Author: User
Tags class definition exception handling

function objects and Lambdas
when you write code, especially when using STL algorithms, you might use function pointers and function objects to solve problems and perform calculations. function pointers and function objects have their pros and cons. For example, a function pointer has the lowest syntax overhead, but does not maintain a range of States, and the function object retains its state, but requires the syntax overhead of the class definition. The
Lambda combines the advantages of function pointers and function objects and avoids their drawbacks. A lambda is similar to a function object in that it is flexible and can remain state, but the difference is that its concise syntax does not require an explicit class definition. With lambda, you can write code that is less complex and error-prone than the equivalent function object code.
The following example compares the use of lambda and function objects. The first example uses a lambda to print to the console whether each element in a vector object is an even or an odd number. The second example uses a function object to accomplish the same task.
Example 1: Using lambda
This example passes a lambda to the For_each function. The lambda prints a result that indicates whether each element in the vector object is an even or an odd number.
Code

Even_lambda.cpp
//compile WITH:CL/EHSC/NOLOGO/W4/MTD
#include <algorithm>
#include < iostream>
#include <vector>
using namespace std;

int main () 
{
 //Create A vector object that contains elements.
 Vector<int> v;
 for (int i = 1; i < ++i) {
  v.push_back (i);
 }

 Count the number of even numbers in the vector by 
 //using the For_each function and a lambda.
 int evencount = 0;
 For_each (V.begin (), V.end (), [&evencount] (int n) {
  cout << n;
  if (n% 2 = 0) {
   cout << "is even" << Endl;
   ++evencount;
  } else {
   cout << "is odd" << Endl
  }
 });

 Print The count of even numbers to the console.
 cout << "There are" << evencount 
  << "even numbers in the vector." << Endl;


Output

1 is even

2 are odd

3 is even

4 are odd

5 is even

6 are odd

7

is even 8 are odd 9 is even There are 4 even numbers in the vector.

Comments
In this example, the third parameter of the For_each function is a lambda. The [&evencount] section specifies the capture clause of the expression, (int n) specifies the argument list, and the remainder specifies the body of the expression.
Example 2: Working with Function objects
Sometimes the lambda is too large to scale substantially on the basis of the previous example. The next example uses the function object (not the lambda) and the for_each function to produce the same result as the example 1. Two examples store the number of even numbers in a vector object. To hold the state of the operation, the Functorclass class uses a reference to store the M_evencount variable as a member variable. To perform this operation, Functorclass implements the function call operator operator (). The Visual C + + compiler generates code that is comparable in size and performance to the lambda code in Example 1. For a basic problem similar to the example in this article, a simpler lambda design might be better than a function object design. However, if you think that the feature might require a significant extension in the future, use the function object design so that code maintenance is simpler.
For more information about operator (), see function calls (C + +).

Code

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

Sing namespace std;
 Class Functorclass {public://The required constructor to this example. Explicit Functorclass (int& evencount): M_evencount (evencount) {}//Function-call operator prints whether th E number is//even or odd.
 If the number is even updates//the counter.

  void operator () (int n) const {cout << n;
   if (n% 2 = 0) {cout << "is even" << Endl;
  ++m_evencount;
  else {cout << ' is odd ' << Endl;
 } private://Default assignment operator to silence warning C4512.

 functorclass& operator= (const functorclass&); int& M_evencount;
The number of even variables in the vector.


};
 int main () {//Create a vector object that contains elements.
 Vector<int> v;
 for (int i = 1; i < ++i) {v.push_back (i); }//Count the number of evenNumbers in the vector by//using the For_each function and a function object.
 int evencount = 0;

 For_each (V.begin (), V.end (), Functorclass (Evencount));
 Print The count of even numbers to the console.

 cout << "There are" << evencount << "even numbers in the vector." << Endl;

Output

1 is even

2 are odd

3 is even

4 are odd

5 is even

6 are odd

7

is even 8 are odd 9 is even There are 4 even numbers in the vector.


declaring a LAMBDA expression
Example 1
Because the lambda expression is typed, you can assign it to the auto variable or function object, as follows:
Code

Declaring_lambda_expressions1.cpp
//compile with:/ehsc/w4
#include <functional>
#include <iostream>

int main ()
{

 using namespace std;

 Assign The lambda expression that adds two numbers to a auto variable.
 Auto F1 = [] (int x, int y) {return x + y;};

 cout << F1 (2, 3) << Endl;

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

 cout << F2 (3, 4) << Endl;
}

Output

5
7

Note
Although many lambda expressions are declared in the body of a function, they can be declared anywhere in the initialization variable.
Example 2
The Visual C + + compiler binds the expression to the captured variable when it declares rather than invokes a lambda expression. The following example shows a lambda expression that captures the local variable I by value and captures the local variable J by reference. Because a lambda expression captures I through a value, reassigning I in the later part of the program does not affect the result of the expression. However, because a lambda expression captures J by reference, Reassigning J affects the result of the expression.
Code

Declaring_lambda_expressions2.cpp
//compile with:/ehsc/w4
#include <functional>
#include < iostream>

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 =;
 j =;

 Call F and print it result.
 cout << F () << Endl;
}

Output

47

Call LAMBDA expression
you can call the lambda expression immediately, as shown in the following code fragment. The second code fragment demonstrates how to pass a lambda as a parameter to the Standard Template Library (STL) algorithm, such as find_if.
Example 1
The following example declares a lambda expression that returns the sum of two integers and calls the expression immediately using Parameters 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

Copy Code code as follows:
9

Example 2
The following example passes a lambda expression as a parameter to the FIND_IF function. Returns true if the lambda expression has an even number of arguments.
Code

Calling_lambda_expressions2.cpp
//compile with:/ehsc/w4
#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 (a);
 Numbers.push_back (a);
 Numbers.push_back (a);
 Numbers.push_back (+);
 Numbers.push_back ();

 Use the find_if function and a lambda expression to find the 
 //A-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 The" the "the" the "the" the "the" the "the" the ""
  << *result << "." &l t;< Endl;
 } else {
  cout << "The list contains no even numbers." << Endl;
 }
}

Output

The even number in the list is 42.

Nested LAMBDA expressions
sample
You can nest lambda expressions in another, as shown in the following example. An internal lambda expression multiplies its arguments by 2 and returns the result. An outer lambda expression invokes an internal lambda expression with its arguments and adds 3 to the result.
Code

Nesting_lambda_expressions.cpp
//compile with:/ehsc/w4
#include <iostream>

int main ()
{
 using namespace std;

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

 Print the result.
 cout << timestwoplusthree << Endl;
}

Output

Copy Code code as follows:
13

Note
In the example, [] (int y) {return y * 2;} is a nested lambda expression.
high-order Lambda functions
example
Many programming languages support the concept of higher-order functions. A higher-order function is a lambda expression that takes another lambda expression as its argument or returns a lambda expression. You can use the function class to make C + + lambda expressions behave like higher-order functions. 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/w4 #include <iostream>
;

 #include <functional> int main () {using namespace std; 
 The following code declares a lambda expression that returns//another lambda expression that adds two.
 The returned lambda expression captures parameter X by value. 
 Auto Addtwointegers = [] (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 multiplies by 2. 
 Auto Higherorder = [] (const function<int (int) >& f, int z) {return F (z) * 2;

 }; 
 Call the lambda expression it bound to higherorder.

 Auto answer = Higherorder (addtwointegers (7), 8);
 Print, which is (7+8) *2.
cout << answer << Endl; }

Output

Copy Code code as follows:
30

Using LAMBDA expressions in functions
sample
You can use lambda expressions in the body of a function. A lambda expression can access any function or data member that the enclosing function can access. You can explicitly or implicitly capture this pointer to provide access to functions and data members of the enclosing class.
You can use this pointer explicitly in a function, as follows:
void Applyscale (const vector<int>& v) const
{
 for_each (V.begin (), V.end (), 
  [This] (int n) {cout & lt;< n * _scale << Endl; });
}

You can also implicitly capture this pointer:

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

The following example displays the Scale class that encapsulates the decimal value.

Function_lambda_expression.cpp
//compile with:/ehsc/w4
#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 (), [=] (int n) {cout < < n * _scale << Endl; });
 }

Private:
 int _scale;
};

int main ()
{
 vector<int> values;
 Values.push_back (1);
 Values.push_back (2);
 Values.push_back (3);
 Values.push_back (4);

 Create a Scale object that scales elements by 3 and apply
 //it to the vector object. Does not modify the vector.
 Scale s (3);
 S.applyscale (values);
}

Output

3
6
9
12

Note
The Applyscale function uses a lambda expression to print the product of decimal digits with each element in a vector object. The lambda expression implicitly captures the this pointer to access the _scale member.


working with Lambda expressions and templates
sample
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 a unary operator-to each element in a vector object. The Print_all function prints each element in a 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. Assumes signed data type.
Template <typename t>
void Negate_all (vector<t>& v)
{
 for_each (V.begin (), V.end (), [] (T & N) {n =-n;})
;

The prints to the console is the vector object of each element.
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 signed integers with a few elements.
 Vector<int> v;
 V.push_back ();
 V.push_back ( -43);
 V.push_back (a);

 Print_all (v);
 Negate_all (v);
 cout << "After Negate_all ():" << Endl;
 Print_all (v);
}

Output


-43 after
negate_all ():
-34
56

Handling Exceptions
sample
The body of a lambda expression follows the principles of structured exception handling (SEH) and C + + exception handling. You can handle the thrown exception in the lambda expression body or defer exception handling to the enclosing scope. The following example uses the For_each function and the lambda expression to populate the value of a vector object into another. It uses the Try/catch block to handle invalid access to the first vector.
Code

Eh_lambda_expression.cpp
//compile with:/ehsc/w4
#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 isn't a valid subscript. It would trigger an exception.
 INDICES[2] = 2;

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


   

Output

Caught ' invalid vector<t> subscript '.

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

Working with LAMBDA expressions and managed types (C++/CLI)
sample
The capture clause of a lambda expression cannot contain a variable that has a managed type. However, you can pass an actual argument with a managed type to the form argument list of a lambda expression. The following example contains a lambda expression that captures the local unmanaged variable ch by value and takes the 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 VA Riables
 //By value and takes a managed the String object as its parameter.
 [=] (String ^s) { 
  Console::WriteLine (s + convert::tochar (ch)); 
 } ("Hello");
}

Output

Hello!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.