# 十二、λ 表达式

## 无捕获 Lambda

我假设您对 C# 中的 lambdas 有经验，那么我们在这里要做的就是介绍 C++ 采用的语法。所有代码片段都来自同一个示例中的同一个文件。

示例:λsample \λsample . CPP

```cpp
          // Create a lambda-expression closure.
          auto lm1 = []()
          {
                wcout << L"No capture, parameterless lambda." << endl;
          };

          // Invoke the lambda.
            lm1();

```

## 带参数的 Lambdas

```cpp
          // Create a lambda closure with parameters.
          auto lm2 = [](int a, int b)
          {
                wcout << a << L" + " << b << " = " << (a + b) << endl;
          };

          lm2(3,4);

```

## 指定λ的返回类型

这里的尾随返回类型是参数规范后的`-> int`。

```cpp
          // 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;

```

## 捕捉外部变量

```cpp
          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

在类成员函数中使用 lambda 时，不能通过引用使用默认捕获。这是因为 lambda 会有一个`this`指针，必须复制。此外，在处理引用计数的智能指针时，经常会遇到 lambda 持有对类的引用的问题。通常情况下，您永远不会回到引用计数为零，从而导致程序内存泄漏。