lambda
来源:互联网 发布:ac68u 广电网络 编辑:程序博客网 时间:2024/05/16 04:52
Capture 子句
Lambda 可在其主体中引入新的变量(用 C++14),它还可以访问(或“捕获”)周边范围内的变量。
1.[var]表示值传递方式捕捉变量var
2.[=]表示值传递方式捕捉所有父作用域的变量(包括this)
3.[&var]表示引用传递捕捉变量var;
4.[&]表示引用传递方式捕捉所有父作用域的变量(包括this);
5.[this]表示值传递方式捕捉当前的this指针。
空 capture 子句 [ ] 指示 lambda 表达式的主体不访问封闭范围中的变量。
可以使用默认捕获模式(标准语法中的 capture-default)来指示如何捕获 lambda 中引用的任何外部变量(使用 capture-default 时,只有 lambda 中提及的变量才会被捕获)
注意事项:
引用捕获可用于修改外部变量,而值捕获却不能实现此操作。 (mutable允许修改副本,而不能修改原始项。)
引用捕获会反映外部变量的更新,而值捕获却不会反映。
引用捕获引入生存期依赖项,而值捕获却没有生存期依赖项。 当 lambda 以异步方式运行时,这一点尤其重要。 如果在异步 lambda 中通过引用捕获本地变量,该本地变量将很可能在 lambda 运行时消失,从而导致运行时访问冲突。
参数列表
在 C++14 中,如果参数类型是泛型,则可以使用 auto 关键字作为类型说明符。 这将告知编译器将函数调用运算符创建为模板。 参数列表中的每个 auto 实例等效于一个不同的类型参数。
可变规范
通常,lambda 的函数调用运算符为 const-by-value,但对 mutable 关键字的使用可将其取消。 它不会生成可变的数据成员。 利用可变规范,lambda 表达式的主体可以修改通过值捕获的变量
返回类型
将自动推导 lambda 表达式的返回类型。 无需使用 auto 关键字,除非指定尾随返回类型。 trailing-return-type 类似于普通方法或函数的返回类型部分。 但是,返回类型必须跟在参数列表的后面,你必须在返回类型前面包含 trailing-return-type 关键字 ->。
如果 lambda 体仅包含一个返回语句或其表达式不返回值,则可以省略 lambda 表达式的返回类型部分。 如果 lambda 体包含单个返回语句,编译器将从返回表达式的类型推导返回类型。 否则,编译器会将返回类型推导为 void
Lambda 体
从封闭范围捕获变量,如前所述。
参数
本地声明变量
类数据成员(在类内部声明并且捕获 this 时)
具有静态存储持续时间的任何变量(例如,全局变量)
// ex10181242.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include<iostream>#include<string>#include <algorithm>#include <cmath>using namespace std;void abssort(float* x, unsigned n) {std::sort(x, x + n,// Lambda expression begins[](float a, float b) {return (std::abs(a) < std::abs(b));} // end of lambda expression);}int add(int a, int b)//error C3533: 参数不能为包含“auto”的类型{return a + b;}void foo(){//}int g_i = 1000;int main(){int a = 1,b= 2;// 简单范例1auto funAdd = [=](int a,int b)->int //优点1(距离):不用提前声明,让定义位于使用的地方附近, 这样无需翻阅多面源代码,函数的缺点是不能在其他函数内定义{return a + b;};cout << "funAdd(a,b) = " << funAdd(a, b) << endl;//捕获范例1 auto refLambda = [&]() { a++; };//优点2(功能:捕获动态变量)以引用的形式捕获任何外部变量引用 也可以单独捕获变量a [&a] refLambda();cout << "a = " << a << endl;//auto valLambda = [=]() { a++; };//错误,以值的形式传递,相当于一个常量值 ,不可以改变//valLambda(a);int c = 3;auto refvalLambda = [&a, b]() {a++; cout << "b = " << b << endl; /*cout << c << endl;*/ };//也可以组合,没有捕获的在表达式中不可用,但不能重复的捕获refvalLambda();cout << "a = " << a << endl;// 优点3(效率):用函数指针不可以形成内联,编译器不会其地址被获取的函数,因为函数地址的概念意味着非内联函数,但lambda可以形成内联// 参数列表2auto foo = [](auto a, auto b) {return a + b; };// 函数中则不可以cout << "foo(1,1) = " << foo(1, 1) << endl;cout << "foo(1.2,1.3) = " << foo(1.2, 1.3) << endl;// 可变规范3 auto mutableValLambda = [=]()mutable {a++; };// 未加mutable 相当于一个常函数 这里的修改也只是一个副本而已cout << "before mutableValLambda a = " << a << endl;mutableValLambda();cout << "after mutableValLambda a = " << a << endl;auto mutableRefLambda = [&]()mutable {a++; };cout << "before mutableRefLambda a = " << a << endl;mutableRefLambda();cout << "after mutableRefLambda a = " << a << endl;//返回类型4auto x1 = [](int i) { return i; };cout << "x1(1) = " << x1(1) << endl;//auto x2 = [] { return{ 1, 2 }; }; wrong //lambda 体int m = 0;int n = 0;[&, n](int a) mutable { m = ++n + a; }(4);// 参数 本地声明变量 因此在调用 lambda 表达式后,变量的值仍保持 0 不变。 mutable 规范允许在 lambda 中修改 n。cout << m << endl << n << endl;// 5,0 static int s_i = 100;cout << "s_i = " << s_i << endl;[&]()mutable{s_i++; }();cout << "s_i = " << s_i << endl;cout << "g_i = " << g_i << endl;[&]()mutable {g_i++; }();cout << "g_i = " << g_i << endl;//在STL较多使用float farr[3] = { 3.2,4.1,-2.1 };abssort(farr, 3);for(auto f :farr) //c++ 11 序列for循环 遍历数组,容器,string以及由begin和end函数定义的序列(即有Iterator)cout << f << ' ';getchar();return 0;}
- Lambda
- lambda
- lambda
- lambda
- Lambda
- lambda
- lambda
- Lambda
- Lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- lambda
- 从一则笑话里分析项目需求的缺陷
- 【37.50%】【codeforces 732D】Exams
- DllRegisterServer的调用失败的问题解决方法
- c#TextBox输入框自动提示、自动完成、自动补全功能
- 火箭、飞行器、探测器的发射
- lambda
- linux下查看centos版本
- 个人常用命令汇总
- Zip Utils--简单优雅的C++接口
- 2016acmicpc现场赛大连赛区D题
- Codeforces Round #374 (Div. 2) C. Journey DP
- C# AD操作
- aapt的常用命令
- 14.2 InnoDB and the ACID Model