当前位置: 首页 > ops >正文

C++ lambda表达式用法说明

       C++ lambda表达式的本质就是重载了 operator(),lambda是一个类,在调用时会进行编译展开。因此lambda表达式对象其实就是一个匿名的functor,所以 lambda 表达式 也叫匿名函数对象。

C++中lambda表达式的构成

         一个标准的lambda表达式包括:捕获列表、参数列表、mutable指示符、异常列表、返回类型(->返回类型)和函数体:

[捕获列表] (形参列表) mutable 异常列表-> 返回类型
{函数体
}

       各项的含义:

  1. 捕获列表:捕获外部变量,捕获的变量可以在函数体中使用,可以省略,即不捕获外部变量。

  2. 形参列表:和普通函数的形参列表一样。可省略,即无参数列表

  3. mutable:mutable 关键字,如果有,则表示在函数体中可以修改捕获变量,根据具体需求决定是否需要省略。

  4. 异常列表:noexcept / throw(...),和普通函数的异常列表一样,可省略,即代表可能抛出任何类型的异常。

  5. 返回类型:和函数的返回类型一样。可省略,如省略,编译器将自动推导返回类型。

  6. 函数体:代码实现。可省略,但是没意义。

捕获列表

       由于lambda表达式是在某函数内定义的,因此我们可能希望其能使用函数内的局部变量,这时则可以使用所谓捕获列表。总体说来,一共有三种捕获方式:值捕获、引用捕获和外部捕获。

值捕获

       值捕获和参数传递中的值传递类似,被捕获的变量的值在Lambda表达式创建时通过值拷贝的方式传入,因此随后对该变量的修改不会影响影响Lambda表达式中的值。注意,不能在lambda表达式中修改捕获变量的值。代码如下:

#include <iostream>using namespace std;int main()
{int nCapture = 13;auto f = [nCapture](int a, int b) -> int{//nCapture = 134;    //不能在lambda表达式中修改捕获变量的值return a + b + nCapture;};cout << f(4, 3) << endl;cout << "nCapture=" << nCapture << endl;return 0;
}

引用捕获

       使用引用捕获一个外部变量,需在捕获列表变量前面加上一个引用说明符&。如下:

#include <iostream>using namespace std;int main()
{int nCapture = 13;auto f = [&nCapture](int a, int b) -> int{cout << "In functor before change nCapture=" << nCapture << endl;    //在调用lamd之前 nCapture = 12345nCapture = 134;cout << "In functor after change nCapture=" << nCapture << endl;     // nCapture = 134return a + b + nCapture;};nCapture = 12345;cout << f(4, 3) << endl;cout << "nCapture=" << nCapture << endl;        //经过了lambda计算后,nCapture值变为修改后的134return 0;
}

         代码结果:

In functor before change nCapture=12345
In functor after change nCapture=134
141
nCapture=134

根据以上说明,引用捕获,可以在lambda函数体修改捕获的值。

隐式捕获

       上面的值捕获和引用捕获都需要我们在捕获列表中显示列出Lambda表达式中使用的外部变量。除此之外,我们还可以让编译器根据函数体中的代码来推断需要捕获哪些变量,这种方式称之为隐式捕获。隐式捕获有两种方式,分别是[=]和[&]。[=]表示以值捕获的方式捕获外部变量,[&]表示以引用捕获的方式捕获外部变量。

lambda表达式的应用场景:

(1)Qt信号槽,槽函数可以用lambda表达式来写;

(2)线程代码

下面是3种捕获方式的简要测试,代码如下:

/*lambda变量捕获测试代码[=]  表示按值捕获,不允许修改;x是只读,无法修改
[&]  &表示引用捕获, 在lambda里可以修改捕获的值
mutable  使用 mutable 表示可以修改按值捕获的副本,并不修改原来的值*/#include <iostream>using namespace std;int main()
{int x = 100;int y = 123;auto f1 = [=]() {//x += 1;  //= 表示按值捕获,不允许修改;x是只读,无法修改};auto f2 = [&]() {x += 100;  //正确,&表示引用捕获};auto f3 = [=, &x] {//y += 100;  //除了x之外,其它的都是按值捕获x += 100;};f2();f3();cout << "x = " << x << endl;auto f4 = [=]() mutable  //使用 mutable 表示可以修改按值捕获的副本,并不修改原来的值{y += 100;cout << "f4 y = " << y << endl;};f4();cout << "y = " << y << endl;return 0;
}

http://www.xdnf.cn/news/11289.html

相关文章:

  • Oracle中decode函数详解
  • 麦克斯韦方程组(彩图完美解释版)
  • 设计模式之单例、工厂、观察者模式
  • 张国荣一生57部电影海报全集
  • Kali-登录暴力破解器工具-medusa使用
  • 【硬件工程师】一次性讲透RS485接口
  • 数字版权管理 DRM 简介
  • 什么是RIA技术,RIA技术概览
  • 常用计算机外部设备有哪些,常用的计算机外设有哪些?
  • [转载]希捷固件门7200.12 CC46固件升级方法
  • Verilog任意分频器设计
  • 史蒂夫·乔布斯 - 简介
  • 个人博客搭建流程(域名、主机、解析、源码、搭建)全程详解
  • Template、ItemsPanel、ItemContainerStyle、ItemTemplate区别和联系
  • JSP基于Java的网咖计费管理系统91y3v程序+源码+数据库+调试部署+开发环境
  • 修改服务器网卡设置,网络适配器怎么设置网络好 完美的三种网络适配器设置方法...
  • linux虚拟机 Ubuntu 安装方法
  • iOS 7新功能汇总!
  • 《你不可不知的人性》刘墉 读书笔记(五)
  • 背单词软件 单词风暴 分享id_周一考研高效背单词系列(一):利用单词软件如何背好单词...
  • 中国最好的一些源码下载站点排名!
  • eclipse3.3.X版本中文语言包下载及安装
  • 基于单片机智能温度控制器系统设计
  • [Unity3D] 3D贪吃蛇
  • Lotus Notes 的新用户最需知道的十件事
  • 网站推广
  • ***常用工具下载大全
  • C语言多线程
  • iPhone1.1.1版简体中文汉化完全教程
  • 港台术语与内地术语之对照