软件开发工程师修炼中|
📂C/C++
🔖cpp
2022-08-10 20:38阅读: 62评论: 0推荐: 0

【C++-笔记】lambda表达式

lambda表达式

对于一个对象或一个表达式,如果可以对其使用调用运算符,则称其为可调用的,可调用对象包括函数、函数指针、重载了调用运算符的类以及本文将介绍的lambda表达式。

lambad表达式简介

可以将lambda表达式当作一个未命名的内联函数,其一般形式如下:

[capture list](parameter list) -> return type {function body}
  • caputure list表示lambda表达式所在函数中定义的局部变量的列表
  • parameter list,return type以及function body与普通函数相同,表示参数列表,返回值以及函数体

lambda表达式可以忽略参数列表和返回类型,但是必须永远包含捕获列表以及函数体:auto f = []{return 42}
对于可调用对象f的调用方式也与普通函数相同:f(),但是需要注意的是:如果没有指定返回值,且函数体中只有一个return语句,那么返回值会通过return语句推断出来,但凡函数体中出现了return之外的语句且没有指定返回值类型,返回类型都会是void。

与普通函数的区别

  1. lambda表达式也像正常函数一样可以接收参数,但是其不可以使用默认参数,也就是说形参的个数必须与传入的实参的个数相同
  2. lambda表达式使用捕获列表:lambda表达式可以使用包含其的函数的局部变量,只有捕获了的变量才可以在lambda表达式的函数体中使用,如果使用未经捕获的变量,即使lambda表达式和该变量处于同一函数当中,代码也会编译错误。另外,捕获列表只用于局部非static变量,lambda可以直接使用局部static变量和它所在函数之外声明的名字。

lambda的捕获

lambda表达式的捕获列表中的变量捕获方式与参数传递类似,也分为值传递与引用传递。

  1. 值捕获。值传递的时候与函数的参数传递有所不同,被捕获的变量在lambda表达式创建的时候就已经被拷贝了,而不是在调用时拷贝,举例如下:
void fun()
{
  int a = 6;
  auto f = [a](){return a;};
  a = 0;
  int x = f(); // x的值应当是6而不是0,因为f在创建时就已经拷贝了a的值,所以结果是6而不是0
}
  1. 引用捕获。当使用引用捕获时,上面的例子的结果就会发生变化:
  int a = 6;
  auto f = [a](){return ++a;};
  a = 0;
  int x = f(); // x的值应当是0而不是7,因为f中保存的是a的引用,而不是拷贝的值

另外,使用引用捕获时,需要注意被引用的对象在lambda执行的时候是存在的
3. 隐式捕获。除了显式的将变量捕获之外,还可以通过隐式捕获让编译器推断我们要使用哪些变量,具体的捕获情况可以见下表(C++ Primer 第五版中文 表10.1)

可变的lambda

默认情况下,lambda不会改变其值捕获的变量,但是如果我们希望改变这个值,就需要在参数列表首使用关键字mutablemutable关键字,用法如下:

int a = 0;
auto f = [a] () mutable {return ++a;};
a = -1;
int j = f(); // j的值是1

对于引用捕获的变量来说,能不能修改在于这个引用是指向的是一个const还是一个非const。

lambda的返回类型

在lambdab表达式简介中提到,如果不仅包含return一条语句,就会默认为返回void,因此这种情况,我们需要根据需要指定返回值类型,具体如下:

[](int i) ->int {if(i < 0) return -i; else return i;};

本文作者:无涯清酒

本文链接:https://www.cnblogs.com/wuyawine/p/16564232.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   无涯清酒  阅读(62)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起