本文中的过程演示如何使用 lambda 表达式。 有关 lambda 表达式的概述,请参见 C++ 中的 Lambda 表达式。 有关 lambda 表达式结构的更多信息,请参见 Lambda 表达式语法

由于类型化 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(, ) << endl; // Assign the same lambda expression to a function object.
function<int(int, int)> f2 = [](int x, int y) { return x + y; }; cout << f2(, ) << endl;
}

输出:


备注

有关更多信息,请参见auto 关键字(类型推导)function 类函数调用 (C++)

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

示例 2

Visual C++ 编译器将一个 lambda 表达式绑定到其捕获的变量上(在声明该表达式而不是调用该表达式时)。 以下示例显示 lambda 表达式,通过值捕获本地变量的 i,并通过引用捕获本地变量的 j。 因为 lambda 表达式通过值捕获 i ,因此 在该程序后面内容中的 i 的重新分配不影响该表达式的结果。 但是,因为 lambda 表达式用引用捕获 j,j 的重新分配确实影响该表达式的结果。

// declaring_lambda_expressions2.cpp
// compile with: /EHsc /W4
#include <functional>
#include <iostream> int main()
{
using namespace std; int i = ;
int j = ; // 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 its result.
cout << f() << endl;
}

输出:


调用 Lambda 表达式

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

示例 1

此示例声明返回两个整数的总和并立即调用表达式。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; }(, );
cout << n << endl;
}

输出:

9

示例 2

此示例将 lambda 表达式作为参数传递给 find_if 函数。 如果其参数是偶数,则 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();
numbers.push_back();
numbers.push_back();
numbers.push_back();
numbers.push_back(); // 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 % ) == ; }); // 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 .

备注

有关 find_if 函数的详细信息,请参阅 find_if。 有关执行常规算法 STL 的函数的更多信息,请参见 <algorithm>

如下例所示,可以嵌套在另一个中的 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 * ; }(x) + ; }(); // Print the result.
cout << timestwoplusthree << endl;
}

输出:

13

备注

在此示例中, [](int y) { return y * 2; } 是嵌套 lambda 表达式。

许多编程语言支持一个高阶函数的概念。一个高阶函数是包含其他 lambda 表达式作为参数或返回 lambda 表达式的 lambda 表达式。 可以使用 函数 类使 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) * ;
}; // Call the lambda expression that is bound to higherorder.
auto answer = higherorder(addtwointegers(), ); // Print the result, which is (7+8)*2.
cout << answer << endl;
}

输出:

30

可以将 lambda 表达式用于类方法的主体中。 lambda 表达式可以访问该封闭方法可以访问的任何方法或数据成员。 您可以显式或隐式捕获 this 指针,以提供对封闭类的方法和数据成员的访问路径。

在方法可以显式使用 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();
values.push_back();
values.push_back();
values.push_back(); // Create a Scale object that scales elements by 3 and apply
// it to the vector object. Does not modify the vector.
Scale s();
s.ApplyScale(values);
}

输出:

3
6
9
12

备注

ApplyScale 方法使用 lambda 表达式打印宽度值和每个产品。vector 对象。 lambda 表达式隐式捕获 this,以便能够访问 _scale 成员。

由于键入 lambda 表达式,因此您可以将它们与 C++ 模板一起使用。 下面的示例显示 negate_all 和 print_all 函数。 negate_all 函数把一元 operator- 应用到 vector 对象中的每个元素上。 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();
v.push_back(-);
v.push_back(); print_all(v);
negate_all(v);
cout << "After negate_all():" << endl;
print_all(v);
}

输出:

-

After negate_all():
- -

备注

有关 C++ 模板的更多信息,请参见 模板

处理异常

 示例

lambda 表达式的主体遵循两个规则结构化异常处理 (SEH) 和 C++ 异常处理。 可以在 lambda 表达式主体中处理引发的异常或将异常处理延迟至封闭作用域。 下面的示例使用 for_each 函数和 lambda 表达式用另一种值的 vector 对象。 使用一个 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(); // Create another vector that contains index values.
vector<int> indices();
indices[] = ;
indices[] = -; // This is not a valid subscript. It will trigger an exception.
indices[] = ; // 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;
};
}

输出:

Caught 'invalid vector<T> subscript'.

备注

有关异常处理的更多信息,请参见Visual C++ 中的异常处理

[转到页首]

lambda 表达式捕获的子句不能包含具有托管类型的变量。 但是,可以将具有托管类型为 lambda 表达式的参数列表的参数。 下面的示例由包含值捕获本地非托管 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");
}

输出:

Hello!

Lambda 表达式的示例的更多相关文章

  1. Lambda 表达式的示例-来源(MSDN)

    本文演示如何在你的程序中使用 lambda 表达式. 有关 lambda 表达式的概述,请参阅 C++ 中的 Lambda 表达式. 有关 lambda 表达式结构的详细信息,请参阅 Lambda 表 ...

  2. Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例

    Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...

  3. Java lambda 表达式常用示例

    实体类 package com.lkb.java_lambda.dto; import lombok.Data; /** * @program: java_lambda * @description: ...

  4. Python3基础 lambda表达式 简单示例

    镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...

  5. Lambda表达式 简介 语法 示例 匿名内部类

    在AS中使用 Lambda 表达式 Demo地址:https://github.com/baiqiantao/MultiTypeTest.git Gradle(Project级别)中添加classpa ...

  6. ASP.NET MVC学前篇之Lambda表达式、依赖倒置

    ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx=>xx>yy);)类似于这样的函数调用语句,里面 ...

  7. Lambda表达式的前世今生

    Lambda 表达式 早在 C# 1.0 时,C#中就引入了委托(delegate)类型的概念.通过使用这个类型,我们可以将函数作为参数进行传递.在某种意义上,委托可理解为一种托管的强类型的函数指针. ...

  8. 委托、Lambda表达式

    本文来自:http://wenku.baidu.com/link?url=o9Xacr4tYocCPhivayRQXfIc9kOZeWBwPn2FZfeF19P4-8YX5CMXs74WB-Y8t0S ...

  9. Lambda表达式、依赖倒置

    ASP.NET MVC学前篇之Lambda表达式.依赖倒置 ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx= ...

随机推荐

  1. 简易的canvas画板

    没事仿照windows画板工具用canvas实现了一个简易版的画板. html: <!doctype html> <html> <head> <meta ch ...

  2. 如何解决css-子div设置margin-top后,父div与子div一起下移的bug?

    根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠. 这是规范引起的普遍问题. 只要给父盒子设 ...

  3. ubuntu禁止系统自动升级之界面操作

    ##第一步:首先找到System Settings,如下图所示: ##第二步:然后找到Solfware & Updates,如下图所示: ##第三步:点击Solfwate & Upda ...

  4. oracle 用户对象权限

    drop user test cascade;create user test identified by test;grant create session to test;grant create ...

  5. 【Python】Java程序员学习Python(三)— 基础入门

    一闪一闪亮晶晶,满天都是小星星,挂在天上放光明,好像许多小眼睛.不要问我为什么喜欢这首歌,我不会告诉你是因为有人用口琴吹给我听. 一.Python学习文档与资料 一般来说文档的资料总是最权威,最全面的 ...

  6. 开源一款私藏Management Studio插件,ProjkyAddin,送给所有使用SQLServer的园友们

    ProjkyAddin 是一款Management Studio 插件,安装包才500多kb,兼容SSMS 2005.SSMS 2008.SSMS 2008 R2.SSMS 2012.SSMS 201 ...

  7. Ubuntn系统(虚拟机)忘记密码的解决方法

    1.重启ubuntu系统,开机时长按shift按键进入GRUB菜单,选择第二个高级选项,enter键进入.如下图: 2.在高级选择中选择Recovery mode模式,键盘按“e”键进入编辑模式.如下 ...

  8. session更换存储,实现在多台服务器共享

    场景 web服务器有多台,每台服务器都会存贮自己的session,session无法在多台服务器共享.所以就需要更换session的存贮空间,存贮在一个共用的空间.通常为了读写速度,我们会选择存贮在内 ...

  9. 解决windows 10英文版操作系统中VS2017控制台程序打印中文乱码问题

    当您在windows 10英文版的操作系统中运行Vs2017控制台应用程序时,程序可能无法正常显示中文,中文都变成了乱码.这是由于大部分中文程序所使用的文字编码与Windows 英文系统的文字编码不同 ...

  10. python多进程(三)

    消息队列 消息队列”是在消息的传输过程中保存消息的容器. 消息队列最经典的用法就是消费者和生成者之间通过消息管道来传递消息,消费者和生成者是不通的进程.生产者往管道中写消息,消费者从管道中读消息.   ...