首页 > 代码库 > Lambda 表达式的示例

Lambda 表达式的示例

本文中的过程演示如何使用 lambda 表达式。 Lambda Expressions in C++.‘ data-guid="411656d77b666e51e15caac8de528191">有关 lambda 表达式的概述,请参见 C++ 中的 Lambda 表达式。 Lambda Expression Syntax.‘ data-guid="df40a218a0617e5e01e20ad28527a334">有关 lambda 表达式结构的更多信息,请参见 Lambda 表达式语法

在本文

 声明 Lambda 表达式

调用 Lambda 表达式

嵌套 Lambda 表达式

高阶 Lambda 函数

通过在方法的 Lambda 表达式

使用与模板的 Lambda 表达式

处理异常

同托管类型的 Lambda 表达式

声明 Lambda 表达式

 示例 1

auto variable or to a function object, as shown here:‘ data-guid="1577825cd5d19173efd8f1e355f35723">由于类型化 lambda 表达式,您可以分配给 auto 变量或到 函数 对象,如下所示:

// 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 an 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;
}

输出:

5
7

备注

auto Keyword (Type Deduction), function Class, and Function Call (C++).‘ data-guid="3903935d9332805dcc459d05b80ac671">有关更多信息,请参见auto 关键字(类型推导)function 类函数调用 (C++)

尽管 lambda 表达式多在方法或函数体中声明,但是也可以在初始化变量的任何地方声明。

示例 2

Visual C++ 编译器将一个 lambda 表达式绑定到其捕获的变量上(在声明该表达式而不是调用该表达式时)。 i by value and the local variable j by reference.‘ data-guid="ae2a9811c3099b634644e9de2eb1a32c">以下示例显示 lambda 表达式,通过值捕获本地变量的 i,并通过引用捕获本地变量的 j。 i by value, the reassignment of i later in the program does not affect the result of the expression.‘ data-guid="001eae44beca4c2412a9663c53ea0600">因为 lambda 表达式通过值捕获 i ,因此 在该程序后面内容中的 i 的重新分配不影响该表达式的结果。 j by reference, the reassignment of j does affect the result of the expression.‘ data-guid="fcca7abac381912ac210a393971be713">但是,因为 lambda 表达式用引用捕获 jj 的重新分配确实影响该表达式的结果。

// 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 = 22;
   j = 44;

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

输出:

47

调用 Lambda 表达式

 如下面的代码段所示,可立即调用 Lambda 表达式。 第二个代码段说明如何将 lambda 作为参数传给标准模板库 (STL) (STL) 算法 (如 find_if

示例 1

5 and 4:‘ data-guid="ca4f2c76fc5980eda2b5bfaa0897c0b9">此示例声明返回两个整数的总和并立即调用表达式。5 和 4参数的 lambda 表达式:

// 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;
}

输出:

?
1
9

示例 2

此示例将 lambda 表达式作为参数传递给 find_if 函数。 true if its parameter is an even number.‘ data-guid="8cc7cbba81fed90d3d66fd4ef07d997b">如果其参数是偶数,则 lambda 表达式返回 true

代码

// 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(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;
    }
}

输出:

The first even number in the list is 42.

备注

find_if function, see find_if.‘ data-guid="501b648c3832eabd14d0c7c14634a5df">有关 find_if 函数的详细信息,请参阅 find_if。 &lt;algorithm&gt;.‘ data-guid="fa3cf021a4ea936a605a17c2734ca16a">有关执行常规算法 STL 的函数的更多信息,请参见 <algorithm>

嵌套 Lambda 表达式

示例

如下例所示,可以嵌套在另一个中的 lambda 表达式。 内部 lambda 表达式将其参数与 2 相乘并返回结果。 外部 lambda 表达式调用其参数的内部 lambda 表达式并将 3 添加到结果。

代码

// 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;
}

输出:

?
1
 

备注

[](int y) { return y * 2; } is the nested lambda expression.‘ data-guid="760f7cd14b0f80619332d0a093fa501e">在此示例中, [](int y) { return y * 2; } 是嵌套 lambda 表达式。

go to top]‘ data-guid="2934928600bb899d29088b7c7f46566a"> 

高阶 Lambda 函数

示例

higher-order function. A higher-order function is a lambda expression that takes another lambda expression as its argument or returns a lambda expression.‘ data-guid="1bd82b51cb4e4c98b92d0d0a38f1a215">许多编程语言支持一个高阶函数的概念。一个高阶函数是包含其他 lambda 表达式作为参数或返回 lambda 表达式的 lambda 表达式。 function class to enable a C++ lambda expression to behave like a higher-order function.‘ data-guid="39f0d4ab7927a8ae206c39bad9ed603a">可以使用 函数 类使 C.C++ Lambda 表达式的行为像高阶函数。 下面的示例演示返回 function 对象和 lambda 表达式采用 function 对象作为其参数的 Lambda 表达式。

// 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 numbers. 
    // 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 that is bound to higherorder. 
    auto answer = higherorder(addtwointegers(7), 8);

    // Print the result, which is (7+8)*2.
    cout << answer << endl;
}

输出:

?
1
 

通过在方法的 Lambda 表达式

示例

可以将 lambda 表达式用于类方法的主体中。 lambda 表达式可以访问该封闭方法可以访问的任何方法或数据成员。 this pointer to provide access to methods and data members of the enclosing class.‘ data-guid="49468aa028648e6fc0357b8af42cb6eb">您可以显式或隐式捕获 this 指针,以提供对封闭类的方法和数据成员的访问路径。

this pointer explicitly in a method, as shown here:‘ data-guid="b5f11525161d32cb8f8c5719739edce5">在方法可以显式使用 this 指针,如下所示:

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

您可隐式也捕获 this 指针:

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

以下示例显示了封装范围值的 Scale 类。

// method_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);
}

输出:

?
1
2
3
4
3
6
9
12

Dd293599.collapse_all(zh-cn,VS.120).gif备注

ApplyScale method uses a lambda expression to print the product of the scale value and each element in a vector object.‘ data-guid="ad06e679003829862b8b91e8d6eafd75">ApplyScale 方法使用 lambda 表达式打印宽度值和每个产品。vector 对象。 this so that it can access the _scale member.‘ data-guid="b9a1c08ccaad311df5aaca1be182daee">lambda 表达式隐式捕获 this,以便能够访问 _scale 成员。

使用与模板的 Lambda 表达式

 示例

由于键入 lambda 表达式,因此您可以将它们与 C++ 模板一起使用。 negate_all and print_all functions.‘ data-guid="b6018b36b33163ed9c1104695444ff64">下面的示例显示 negate_all 和 print_all 函数。 negate_all function applies the unary operator- to each element in the vector object.‘ data-guid="b17c5ab9fd17f0c55d3deb6d75a64f29">negate_all 函数把一元 operator- 应用到 vector 对象中的每个元素上。 print_all function prints each element in the vector object to the console.‘ data-guid="00137aabad6b70f7628173e82fb5cc11">print_all 函数打印vector 对象中的每个元素到控制台。

// 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; });
}

// 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 signed integers with a few elements.
    vector<int> v;
    v.push_back(34);
    v.push_back(-43);
    v.push_back(56);

    print_all(v);
    negate_all(v);
    cout << "After negate_all():" << endl;
    print_all(v);
}

输出:

34
-43
56
After negate_all():
-34
43
-56

Dd293599.collapse_all(zh-cn,VS.120).gif备注

Templates.‘ data-guid="b28118192a5fefdc3e7784bc749a4316">有关 C++ 模板的更多信息,请参见 模板

处理异常

 示例

lambda 表达式的主体遵循两个规则结构化异常处理 (SEH) 和 C++ 异常处理。 可以在 lambda 表达式主体中处理引发的异常或将异常处理延迟至封闭作用域。 下面的示例使用 for_each 函数和 lambda 表达式用另一种值的 vector 对象。 try/catch block to handle invalid access to the first vector.‘ data-guid="3728188f8e545dc738a2bfd8b9191827">使用一个 try/catch 块处理到第一个矢量的无效访问。

// 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 is not a valid subscript. It will 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 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;
    };
}

输出:

?
1
Caught ‘invalid vector<T> subscript‘.

Dd293599.collapse_all(zh-cn,VS.120).gif备注

Exception Handling in Visual C++.‘ data-guid="01495aa04d6415029313c880f6d94fb4">有关异常处理的更多信息,请参见Visual C++ 中的异常处理

go to top]‘ data-guid="2934928600bb899d29088b7c7f46566a">[转到页首]

同托管类型的 Lambda 表达式

 示例

lambda 表达式捕获的子句不能包含具有托管类型的变量。 但是,可以将具有托管类型为 lambda 表达式的参数列表的参数。 ch by value and takes a System.String object as its parameter.‘ data-guid="122c34491af6f1c15685358efbde1b0d">下面的示例由包含值捕获本地非托管 ch 变量并采用 System.String 对象作为其参数的 Lambda 表达式。

// 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");
}

输出:

?
1
Hello!