left-icon

C++ Succinctly®
by Michael McLaughlin

Previous
Chapter

of
A
A
A

CHAPTER 12

Lambda Expressions

Lambda Expressions


No-Capture Lambdas

I assume that you have experience with lambdas from C#, so what we will do here is cover the syntax that C++ has adopted. All code snippets are from the same file in the same sample.

Sample: LambdaSample\LambdaSample.cpp

     // Create a lambda-expression closure.

     auto lm1 = []()

     {

          wcout << L"No capture, parameterless lambda." << endl;

     };

     // Invoke the lambda.

       lm1();

Lambdas with Parameters

     // Create a lambda closure with parameters.

     auto lm2 = [](int a, int b)

     {

          wcout << a << L" + " << b << " = " << (a + b) << endl;

     };

     lm2(3,4);

Specifying a Lambda’s Return Type

The trailing return type here is -> int after the parameter specification.

     // Create a lambda closure with a trailing return type.

     auto lm3 = [](int a, int b) -> int

     {

          wcout << a << L" % " << b << " = ";

          return a % b;

     };

     wcout << lm3(7, 5) << endl;

Capturing Outside Variables

     int a = 5;

     int b = 6;

     // Capture by copy all variables that are currently in the scope.

     // Note also that we do not need to capture the closure;

     // here we simply invoke the anonymous lambda with the

     // () after the closing brace.

     [=]()

     {

          wcout << a << L" + " << b << " = " << (a + b) << endl;

          //// It's illegal to modify a here because we have

          //// captured by value and have not specified that

          //// this lambda should be treated as mutable.

          //a = 10;

     }();

     [=]() mutable -> void

     {

          wcout << a << L" + " << b << " = " << (a + b) << endl;

          // By marking this lambda as mutable, we can now modify a.

          // Since we are capturing by value, the modifications

          // will not propagate outside.

          a = 10;

     }();

     wcout << L"The value of a is " << a << L"." << endl;

     [&]()

     {

          wcout << a << L" + " << b << " = " << (a + b) << endl;

          // By capturing by reference, we now do not need

// to mark this as mutable.

          // Because it is a reference, though, changes now

          // propagate out.

          a = 10;

     }();

     wcout << L"The value of a is " << a << L"." << endl;

     // Here we specify explicitly that we are capturing a by

     // value and b as a reference.

     [a,&b]()

     {

          b = 12;

          wcout << a << L" + " << b << " = " << (a + b) << endl;

     }();

     // Here we specify explicitly that we are capturing b as

     // a reference and that all other captures should be by

     // value.

     [=,&b]()

     {

          b = 15;

          wcout << a << L" + " << b << " = " << (a + b) << endl;

     }();

     // Here we specify explicitly that we are capturing a by

     // value and that all other captures should be by reference.

     [&,a]()

     {

          b = 18;

          wcout << a << L" + " << b << " = " << (a + b) << endl;

       }();

Lambdas in Class-Member Functions

When you use a lambda in a class-member function, you cannot use a default capture by reference. This is because the lambda will be provided with a this pointer, and it must be copied. Also, when dealing with reference-counted smart pointers, it’s common to run into problems with the lambda holding a reference to the class. Usually you will never get back to a reference count of zero, causing a memory leak in your program.

Scroll To Top
Disclaimer
DISCLAIMER: Web reader is currently in beta. Please report any issues through our support system. PDF and Kindle format files are also available for download.

Previous

Next



You are one step away from downloading ebooks from the Succinctly® series premier collection!
A confirmation has been sent to your email address. Please check and confirm your email subscription to complete the download.