C++中Lambda表达式/Lambda 函数/匿名函数

C++ Lambda表达式/Lambda 函数/匿名函数

C++11 提供了对匿名函数的支持,称为 Lambda 函数(也叫 Lambda 表达式)。

Lambda 表达式把函数看作对象。Lambda 表达式可以像对象一样使用,比如可以将它们赋给变量和作为参数传递,还可以像函数一样对其求值。

Lambda 表达式本质上与函数声明非常类似。Lambda 表达式具体形式如下:

lambda表达å¼çç»æåç´ 

  1. 捕获列表。

  2. 参数列表 (可选)。

  3. 可变说明 (可选)。

  4. 异常说明(可选)。

  5. 返回类型(可选)。

  6. 表达式主体

 

  • 捕获列表

捕获列表可以为空。C++变量传递有传值和传引用的区别。可以通过前面的[ ]来指定:

[]      // 沒有定义任何变量。使用未定义变量会引发错误。
[x, &y] // x以传值方式传入(默认),y以引用方式传入。
[&]     // 任何被使用到的外部变量都隐式地以引用方式加以引用。
[=]     // 任何被使用到的外部变量都隐式地以传值方式加以引用。
[&, x]  // x显式地以传值方式加以引用。其余变量以引用方式加以引用。
[=, &z] // z显式地以引用方式加以引用。其余变量以传值方式加以引用。
  • 参数列表

除了捕获变量之外,lambda还可以接受输入参数。参数列表是可选的,在大多数方面类似于函数的参数列表。在C++14中,如果参数类型是通用的,则可以使用auto关键字作为类型说明符。这告诉编译器将函数调用操作符创建为模板。参数列表中的每个auto实例等同于不同的类型参数。

auto y = [] (auto first, auto second)
{
    return first + second;
};
  • 可变说明

mutable使lambda表达式的主体能够修改由传值捕获的变量。如以下例子:

#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;
}

输出为:

5
0

因为变量n是通过传值捕获的,所以0在调用lambda表达式之后它的值仍然存在。所述mutable允许n被lambda表达式修改。

  • 异常说明

您可以使用noexcept来指示lambda表达式不会抛出任何异常。与普通函数一样,如果lambda表达式使用了noexcept并且lambda抛出了异常,则Visual C ++编译器会生成警告C4297

  • 返回类型

如果lambda主体只包含一个return语句或表达式不返回值,则可以省略lambda表达式的返回类型部分。如果lambda主体包含一个return语句,则编译器会从返回表达式的类型中推断出返回类型。否则,编译器会将返回类型推断为void。请考虑以下示例代码片段,说明此原则。

auto x1 = [](int i){ return i; }; // 正确: 返回类型为 int
auto x2 = []{ return{ 1, 2 }; };  // 错误: 返回类型将为 void
                                  // 大括号初始化列表的返回类型是不合法的
  • 表达式主体

与普通函数类似,lambda表达式的主体可以包含函数的主体能包含的任何内容。普通函数和lambda表达式的主体都可以访问这些变量:

  1. 捕获列表中的变量
  2. 参数列表中的变量
  3. 本地声明的变量
  4. 类的数据成员
  5. 具有静态存储持续时间的任何变量 - 例如,全局变量
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值