网址站,做外贸业务去哪些网站,网站备案完毕 怎样建设网站,wordpress archives一、Lambda表达式概述
c在c11标准中引入了lambda表达式#xff0c;一般用于定义匿名函数#xff0c;lambda表达式#xff08;也称为lambda函数#xff09;是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常#xff0c;lambda用于封装传递给算法或异步…一、Lambda表达式概述
c在c11标准中引入了lambda表达式一般用于定义匿名函数lambda表达式也称为lambda函数是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常lambda用于封装传递给算法或异步方法的几行代码 。本文主要介绍Lambda的工作原理以及使用方法。
二、Lambda表达式定义
1、Lambda表达式示例
下例是MS官网上的一个示例
#include algorithm
#include cmathvoid 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);
}
这个实例中直接将排序函数的实现写在应该传递函数的位置省去了定义排序函数的过程对于这种不需要复用且短小的函数直接传递函数体可以增加代码的可读性。
2、Lambda表达式语法定义 capture 子句在 C 规范中也称为 Lambda 引导。 参数列表可选。 也称为 Lambda 声明符 mutable 规范可选。 exception-specification可选。 return-type 返回值可选。 Lambda 体。
3、Lambda表达式参数详解
1捕获列表
上面介绍完了lambda表达式的各个成分其实很多部分和正常的函数没什么区别其中最大的一个不同点就是捕获列表。我在刚开始用lambda表达式的时候还一直以为这个没啥用只是用一个 [] 来标志着这是一个lambda表达式。后来了解了才知道原来这个捕获列表如此强大甚至我觉得捕获列表就是lambda表达式的灵魂。下面先介绍几种常用的捕获方式。
[] 什么也不捕获无法lambda函数体使用任何
[] 按值的方式捕获所有变量
[] 按引用的方式捕获所有变量
[, a] 除了变量a之外按值的方式捕获所有局部变量变量a使用引用的方式来捕获。这里可以按引用捕获多个例如 [, a, b,c]。这里注意如果前面加了后面加的具体的参数必须以引用的方式来捕获否则会报错。
[, a] 除了变量a之外按引用的方式捕获所有局部变量变量a使用值的方式来捕获。这里后面的参数也可以多个例如 [, a, b, c]。这里注意如果前面加了后面加的具体的参数必须以值的方式来捕获。
[a, b] 以值的方式捕获a引用的方式捕获b也可以捕获多个。
[this] 在成员函数中也可以直接捕获this指针其实在成员函数中[]和[]也会捕获this指针。 class A{public:int i_ 0;void func(int x, int y){auto x1 []{ return i_; }; // error没有捕获外部变量auto x2 []{ return i_ x y; }; // OK捕获所有外部变量auto x3 []{ return i_ x y; }; // OK捕获所有外部变量auto x4 [this]{ return i_; }; // OK捕获this指针auto x5 [this]{ return i_ x y; }; // error没有捕获x、yauto x6 [this, x, y]{ return i_ x y; }; // OK捕获this指针、x、yauto x7 [this]{ return i_; }; // OK捕获this指针并修改成员的值}};int a 0, b 1;auto f1 []{ return a; }; // error没有捕获外部变量auto f2 []{ return a; }; // OK捕获所有外部变量并对a执行自加运算auto f3 []{ return a; }; // OK捕获所有外部变量并返回aauto f4 []{ return a; }; // errora是以复制方式捕获的无法修改auto f5 [a]{ return a b; }; // error没有捕获变量bauto f6 [a, b]{ return a (b); }; // OK捕获a和b的引用并对b做自加运算auto f7 [, b]{ return a (b); }; // OK捕获所有外部变量和b的引用并对b做自加运算 2参数列表
Lambda 既可以捕获变量也可以接受输入参数。 参数列表在标准语法中称为 Lambda 声明符是可选的它在大多数方面类似于函数的参数列表。
auto function [] (int first, int second){return first second;
};function(100, 200);3可变规格mutable
mutable修饰符 默认情况下Lambda函数总是一个const函数mutable可以取消其常量性。在使用该修饰符时参数列表不可省略即使参数为空。
#include iostream
using namespace std;int main()
{int m 0;int n 0;[, n] (int a) mutable { m n a; }(4);cout m endl n endl;
}4异常说明
你可以使用 throw() 异常规范来指示 lambda 表达式不会引发任何异常。与普通函数一样如果 lambda 表达式声明 C4297 异常规范且 lambda 体引发异常Visual C 编译器将生成警告 throw() 。
int main() // C4297 expected
{ []() throw() { throw 5; }();
}5返回类型
Lambda表达式的返回类型会自动推导。除非你指定了返回类型否则不必使用关键字。返回型类似于通常的方法或函数的返回型部分。但是返回类型必须在参数列表之后并且必须在返回类型-之前包含类型关键字。如果lambda主体仅包含一个return语句或该表达式未返回值则可以省略Lambda表达式的return-type部分。如果lambda主体包含一个return语句则编译器将从return表达式的类型中推断出return类型。否则编译器将返回类型推导为void。
auto x1 [](int i){ return i; };6Lambda函数体
Lambda表达式的lambda主体标准语法中的复合语句可以包含普通方法或函数的主体可以包含的任何内容。普通函数和lambda表达式的主体都可以访问以下类型的变量
- 捕获变量
- 形参变量
- 局部声明的变量
- 类数据成员当在类内声明**this**并被捕获时
- 具有静态存储持续时间的任何变量例如全局变量#include iostream
using namespace std;int main()
{int m 0;int n 0;[, n] (int a) mutable { m n a; }(4);cout m endl n endl;
}