Lambda 表达式的示例
本文中的过程演示如何使用 lambda 表达式。 有关 lambda 表达式的概述,请参见 C++ 中的 Lambda 表达式。 有关 lambda 表达式结构的更多信息,请参见 Lambda 表达式语法。
声明 Lambda 表达式
示例 1
由于类型化 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 表达式
示例 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 表达式的 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 表达式的示例的更多相关文章
- Lambda 表达式的示例-来源(MSDN)
本文演示如何在你的程序中使用 lambda 表达式. 有关 lambda 表达式的概述,请参阅 C++ 中的 Lambda 表达式. 有关 lambda 表达式结构的详细信息,请参阅 Lambda 表 ...
- Java基础学习总结(44)——10个Java 8 Lambda表达式经典示例
Java 8 刚于几周前发布,日期是2014年3月18日,这次开创性的发布在Java社区引发了不少讨论,并让大家感到激动.特性之一便是随同发布的lambda表达式,它将允许我们将行为传到函数里.在Ja ...
- Java lambda 表达式常用示例
实体类 package com.lkb.java_lambda.dto; import lombok.Data; /** * @program: java_lambda * @description: ...
- Python3基础 lambda表达式 简单示例
镇场诗: 诚听如来语,顿舍世间名与利.愿做地藏徒,广演是经阎浮提. 愿尽吾所学,成就一良心博客.愿诸后来人,重现智慧清净体.-------------------------------------- ...
- Lambda表达式 简介 语法 示例 匿名内部类
在AS中使用 Lambda 表达式 Demo地址:https://github.com/baiqiantao/MultiTypeTest.git Gradle(Project级别)中添加classpa ...
- ASP.NET MVC学前篇之Lambda表达式、依赖倒置
ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx=>xx>yy);)类似于这样的函数调用语句,里面 ...
- Lambda表达式的前世今生
Lambda 表达式 早在 C# 1.0 时,C#中就引入了委托(delegate)类型的概念.通过使用这个类型,我们可以将函数作为参数进行传递.在某种意义上,委托可理解为一种托管的强类型的函数指针. ...
- 委托、Lambda表达式
本文来自:http://wenku.baidu.com/link?url=o9Xacr4tYocCPhivayRQXfIc9kOZeWBwPn2FZfeF19P4-8YX5CMXs74WB-Y8t0S ...
- Lambda表达式、依赖倒置
ASP.NET MVC学前篇之Lambda表达式.依赖倒置 ASP.NET MVC学前篇之Lambda表达式.依赖倒置 前言 随着上篇文章的阅读,可能有的朋友会有疑问,比如(A.Method(xxx= ...
随机推荐
- Drupal8入门文章推荐
1.<drupal 8 入门 > 2.<初探drupal8>
- 通过代码动态创建IIS站点
对WebApi进行单元测试时,一般需要一个IIS站点,一般的做法,是通过写一个批处理的bat脚本来实现,其实通过编码,也能实现该功能. 主要有关注三点:应用程序池.Web站点.绑定(协议类型:http ...
- 调用Android中的软键盘
我们在Android提供的EditText中单击的时候,会自动的弹 出软键盘,其实对于软键盘的控制我们可以通过InputMethodManager这个类来实现.我们需要控制软键盘的方式就是两种一个是像 ...
- 网络 OSI参考模型与TCP/IP模型
ISO是国际标准化组织.OSI,开放互联系统.IOS,思科交换机和路由器的操作系统. TCP/IP模型是OSI模型的简化.所有的互联网协议都是基于OSI模型开发的. 分层:便于管理,每层只管理下层,总 ...
- WEB API 支持多种端的后台
一套代码,支持多种平台 1. 支持web 可以js获取webapi的数据源.利用mvvm组织展现在html上. 2.支持安卓. post方法,安卓获取webapi的数据.
- Oracle EBS PO退货失败
无法读取例程 &ROUTINE 中配置文件选项 INV_DEBUG_TRACE 的值. 系统-配置文件-地点层 INC%调试%踪 是 select * from po_interface_e ...
- Sqlserver2014 迁移数据库
由于当初安装sqlserver 的时候选择默认安装的路径,导致现在c盘爆满,安装不了其它软件.因此想到了迁移数据库,网上搜索了一些简介,但是缺少一些步骤,导致数据库附加的时候失败.现总结如下: 1.将 ...
- java开发初识
jdk目录相关介绍: bin:存放的是java的相关开发工具 db:顾名思义jre附带的轻量级数据库 include:存放的是调用系统资源的接口文件 jre:java的运行环境 lib:核心的类库 s ...
- PHP设计模式系列 - 建造者模式
什么是建造者模式 建造者模式主要是为了消除其它对象复杂的创建过程. 设计场景 有一个用户的UserInfo类,创建这个类,需要创建用户的姓名,年龄,金钱等信息,才能获得用户具体的信息结果. 创建一个U ...
- MySQL知识总结(四)二进制日志
1 定义 bin-log日志记录了所有的DDL和DML的语句,但不包括查询的语句,语句以事件的方式保存,描述了数据的更改过程,此日志对发生灾难时数据恢复起到了极为重要的作用. 2 开启 mysql默认 ...