C++ 中的Lambda表达式写法

2020-01-06 16:37:34王冬梅

如果 lambda 体仅包含一个返回语句或其表达式不返回值,则可以省略 lambda 表达式的返回类型部分。 如果 lambda 体包含单个返回语句,编译器将从返回表达式的类型推导返回类型。 否则,编译器会将返回类型推导为 void 。


#include <iostream>
#include <typeinfo>
int main() {
 autolambda1 = [](int i) {return i;};
 autolambda2 = [](int i) -> bool {return i;};
 autolambda3 = [](int i) -> float {return i;};
 /* auto lambda4 = []{ return {1, 2}; };*/ // ERROR: return type is void
            // cannot deduce lambda return type
 
 autox1 = lambda1(10);
 autox2 = lambda2(10);
 autox3 = lambda3(10);
 
 std::cout << x1 << " " << typeid(x1).name() << std::endl;
 std::cout << x2 << " " << typeid(x2).name() << std::endl;
 std::cout << x3 << " " << typeid(x3).name() << std::endl;
 return 0;
}

typeinfo的功能是获取一个变量的类型,由于它的实现依赖于编译器,所以在不同平台下的输出可能不完全一样。小喵这边的输出是:

10 i
1 b
10 f

可以看出,三个lambda的输出是不相同的。默认情况下,会返回一个最直接的类型。

6、lambda体

lambda体其实和函数体几乎完全相同。

lambda 表达式的 lambda 体(标准语法中的 compound-statement )可包含普通方法或函数的主体可包含的任何内容。 普通函数和 lambda 表达式的主体均可访问以下变量类型:

从封闭范围捕获变量,如前所述(Capture)。

参数

本地声明变量

类数据成员(在类内部声明并且捕获  this  时)

具有静态存储持续时间的任何变量(例如,全局变量)

这里要注意我们在Capture 规范中说到的值访问和引用访问的特点。

下面的例子都是MSDN上给出的。

以下示例包含通过值显式捕获变量 n 并通过引用隐式捕获变量  m 的 lambda 表达式:


// captures_lambda_expression.cpp 
// compile with: /W4 /EHsc 
#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 是通过值捕获的,因此在调用 lambda 表达式后,变量的值仍保持  0 不变。   mutable 规范允许在 lambda 中修改  n 。

尽管 lambda 表达式只能捕获具有自动存储持续时间的变量,但你可以在 lambda 表达式的主体中使用具有静态存储持续时间的变量。 以下示例使用 generate 函数和 lambda 表达式为  vector 对象中的每个元素赋值。 lambda 表达式将修改静态变量以生成下一个元素的值。