C++ 中的Lambda表达式写法

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


pNums = make_unique<vector<int>>(nums); 
//... 
  auto a = [ptr = move(pNums)]() 
  { 
   // use ptr 
  };

2、参数列表

除了捕获变量,lambda 还可接受输入参数。 参数列表(在标准语法中称为 lambda 声明符 )是可选的,它在大多数方面类似于函数的参数列表。


autoadd = [] (int first, int second) 
{ 
 return first + second; 
};

在 C++14 中,如果参数类型是泛型,则可以使用 auto 关键字作为类型说明符。 这将告知编译器将函数调用运算符创建为模板。 参数列表中的每个 auto 实例等效于一个不同的类型参数。


autoadd = [] (autofirst, autosecond) 
{ 
 return first + second; 
};

lambda 表达式可以将另一个 lambda 表达式作为其参数。

由于参数列表是可选的,因此在不将参数传递到 lambda 表达式,并且其 lambda-declarator: 不包含  exception-specification 、 trailing-return-type 或  mutable 的情况下,可以省略空括号。

[]{}; // 这就是最简单的lambda表达式

3、可变规范

通常,lambda 的函数调用运算符为 const-by-value,但对 mutable 关键字的使用可将其取消。 它不会生成可变的数据成员。 利用可变规范,lambda 表达式的主体可以修改通过值捕获的变量。 本文后面的一些示例将显示如何使用  mutable 。


#include <iostream>
int main()
{
 int n = 10;
 autolambda1 = [n](int x) {
  /* ++ n; */ // 这句编译会出错,错误信息如下:
     // error: cannot assign to a variable captured
     // by copy in a non-mutable lambda
  return x + n;
 };
 autolambda2 = [n](int x) mutable {
  ++ n;
  return x + n;
 };
 std::cout << lambda1(5) << " " << n << std::endl;
 std::cout << lambda2(5) << " " << n << std::endl;
 return 0;
}

输出的结果是:

可以看出n确实是通过值来访问,在lambda1中,我们运行++n,在编译的时候会报错。使用mutable修饰之后,就可以修改参数(副本)的值。

4、异常规范

你可以使用 throw() 异常规范来指示 lambda 表达式不会引发任何异常。与普通函数一样,如果 lambda 表达式声明  C4297 异常规范且 lambda 体引发异常,Visual C++ 编译器将生成警告  throw() ,如下所示:


// throw_lambda_expression.cpp 
// compile with: /W4 /EHsc 
int main() // C4297 expected 
{ 
 []() throw() { throw 5; }(); 
}

在MSDN的异常规范 [5] 中,明确指出异常规范是在 C++11 中弃用的 C++ 语言功能。因此这里不建议不建议大家使用。

5、返回类型

将自动推导 lambda 表达式的返回类型。 无需使用 auto 关键字,除非指定 尾随返回类型 。 trailing-return-type 类似于普通方法或函数的返回类型部分。 但是,返回类型必须跟在参数列表的后面,你必须在返回类型前面包含 trailing-return-type 关键字  -> 。