C++——Lambdas表达式

许多编程语言支持 匿名函数的概念,这些函数有主体,但是,没有名称。

lambda 是使用匿名功能相关的编程方法。 lambda 隐式定义函数对象类和构造函数对象。选件类类型。

可以简单理解为:lambda是一种特殊的表达式,没有函数声明,却有实现主体。

lambdas表达式语法:

lambda 表达式的结构元素

在图中的标注,如下所示:

  1. lambda introducer (称为捕获子句在本主题后面)

  2. lambda 参数声明列表 (称为 参数列表在本主题后面)

  3. 可变规范 (称为 可变规范在本主题后面)

  4. 异常规范 (称为 异常规范在本主题后面)

  5. lambda 返回类型子句 (称为 返回类型在本主题后面)

  6. 复合语句 (称为 lambda 主体在本主题后面)

一、捕获子句

[&total, factor] //total按引用传递, factor按值传递
[&, factor]//除了factor按值传递,其他都按引用传递
[=, &total]//除了total按引用传递,其他都按值传递

 二、参数列表

Lambda 表达式的参数列表与类似的参数列表的函数,但以下情况除外:

  • 参数列表中不能有默认参数。

  • 参数列表中不能有一个可变长度参数列表。

  • 参数列表中不能有未命名的参数。

三、可变规范

实例:返回x+y

void main()
{
    int x = 1;
    int y = 2;
    int z = [=]{return x + y;}();
}

四、异常规范

 抛出异常:

int main() // C4297 expected
{
   []() throw() { throw 5; }();
}

五、返回类型

实例一:用引用传递才能修改lambdas范围内的变量的值,指定返回类型为int,如果不指定返回类型,主体只能有return语句。

void main()
{
    int x = 1;
    int y = 2;
    int z = [&]() -> int{x++; return x + y;}();
}

 实例二:换一种表达

参数列表中临时变量为a,赋值为4。

n按值传递,但是加上mutable修饰可变,但是在主体内++n修改了的是按值传递后的n,至于main函数中的n不改变值,

与引用传递不同。

int main()
{
	int m = 0, n = 0;
	[&, n] (int a) mutable { m = ++n + a; }(4);
	cout << m << endl << n << endl;
}

六、lambdas主体

尽管 lambda 表达式可以只捕获自动存储持续时间的变量,您可以使用 lambda 表达式的正文中的静态存储持续时间的变量。

void main()
{
    static int x = 1;
    [](){return x++;}();

}

等效的是:

void main()
{
    int x = 1;
    [&](){return x++;}();

}

上述两个结果都是:2 

但是与如下结果不同:

void main()
{
    int x = 1;
    [=]() mutable{return x++;}();

}

结果是1

就是因为一个是引用传值,一个是按值传递。

通过可以说已经有了对lambdas表达式基本的了解了:

引出几个algorithm中的函数来阐述lambdas表达式在容器中的应用,推广到以后自己的项目中能更高效:

一、for_each()函数:一般是遍历从 容器指定位置开始 到 容器指定位置结束的 功能

for_each(_InIt _First, _InIt _Last, _Fn1 _Func);

_InIt _First:容器指定位置开始

_InIt _Last:容器指定位置结束

_Fn1 _Func:lambdas表达式

void main()
{
	vector<int> v(9, 1);

	for_each(v.begin(), v.end(), [] (int n) {cout << n << endl;});
	system("pause");
}

二、generate()函数

generate(_FwdIt _First, _FwdIt _Last, _Fn0 _Func);

_Fn0 _Func:能接收参数 与 _Fn1 _Func不同(不能接收参数)

generate改变已规定容器大小指定位置的值。

void main()
{
	static int nextValue = 1;
	vector<int> v(9, 1);

	generate(v.begin(), v.end(), [] { return nextValue++; });
	for_each(v.begin(), v.end(), [] (int n) {cout << n << endl;});
	system("pause");
}

三、generate_n()函数:

可以规定生成大小,并对指定位置进行赋值

generate_n(_OutIt _Dest, _Diff _Count, _Fn0 _Func);

_OutIt _Dest:指定位置开始

_Diff _Count:指定生成大小

void main()
{
	static int nextValue = 1;
	vector<int> v(9,1);
	
	generate_n(back_inserter(v), 9, [] { return nextValue++; });
	for_each(v.begin(), v.end(), [](int n){cout << n << endl;});
	system("pause");
}

其中back_inserter(v)函数:指的是在容器v的末尾的位置。不过要多包一个头文件<iterator>。

猜你喜欢

转载自blog.csdn.net/u012198575/article/details/83339182