Moderm Effective C++ 条款31 第206提到了按引用捕获局部变量和函数形参时,如果lambda式的生命期依赖于局部变量和函数形参的生命期,需注意空悬引用的问题。

原书的例子不够直观,把它改写后进行说明。

 #include "pch.h"
#include <iostream>
#include <vector>
#include <functional> using FilterContainer = std::vector<std::function<bool(int)>>;
FilterContainer filter; void addDivisorFilter() { auto divisor = ;
filter.emplace_back([&](int value) {
return value % divisor == ;
});
std::cout << divisor << std::endl;
} int main()
{
addDivisorFilter();
addDivisorFilter();
std::cout << &filter[] << std::endl;
std::cout << filter[]() < <std::endl; //Unexpected function calls
std::cout << &filter[] << std::endl;
std::cout << filter[]() << std::endl; //Unexpected function calls
}
filter是一个筛选器函数(筛选5的倍数)集合,line23,预期输出0,因为4不是5的倍数。line23,预期输出1.
实际结果则是

箭头1指向的结果看起来正确,箭头2指向的结果不正确,但这两个结果其实都是未定义行为的结果,不符合预期。

跟踪代码如下:

红框部分显示divisor是个很大的负数,不是预期的数字5。所以两次lambda调用结果输出都是0。

问题就出在lambda引用了divisor这个局部变量,addDivisorFilter函数出了代码块后,divisor消亡,lambda指向了一个空悬的divisor引用,当调用lambda时,它里面的divisor是一个未知值。

用这个未知值来进行模计算,当然会出错了。

未完待续...

C++ lamba使用的更多相关文章

  1. 【lamba】java 8的新特性

    看到lamba表达式用起来还不错,找了几篇文章学习下: 所以结合之前两个反编译的结果可以看到,lamdba表达式运行整体思路大致如下: 1. lamdba表达式被编译生成当前类的一个私有静态方法 2. ...

  2. lamba匿名函数与内置函数/递归

    max 循环出的参数给func,func的返回值给key,然后比较那个返回值max(salary,key=func) 匿名函数:max(salary,key=lamba x:salaries[x]) ...

  3. lamba数据架构以及数据湖

    面试大数据项目,面试过程中发现面试官提到的两个概念没有搞清楚: 1. lamba数据架构:这个概念的提出是由storm的作者提出来的,其实主旨就是想要说明,数据的处理分成三层,一类是批处理程序(bat ...

  4. Java8中list.sort的lamba表达式

    最近写代码,需要对list集合排序,IDEA总是黄色警告: Reports calls to Collections.sort(list, comparator) which could be rep ...

  5. python高阶函数(Map、Reduce、Filter、lamba)

    Map函数 map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回. 代码如下: >>> def f(x): . ...

  6. 【c++】c++ 11之lamba表达式

    C++ lambda表达式与函数对象 lambda表达式是C++11中引入的一项新技术,利用lambda表达式可以编写内嵌的匿名函数,用以替换独立函数或者函数对象,并且使代码更可读.但是从本质上来讲, ...

  7. [C/C++11语法]_[0基础]_[lamba 表达式介绍]

    场景 lambda 表达式在非常多语言里都有一席之地,由于它的原因,能够在函数里高速定义一个便携的函数,或者在函数參数里直接高速构造和传递. 它能够说是匿名函数对象,一般仅仅适用于某个函数内,仅仅做暂 ...

  8. linq 和lamba表达式

    一.什么是Linq(what)二.Linq的优点(why)三.Linq查询的步骤(how)四.查询基本操作五.結合實例代碼(具體聯繫用linqtosql來寫的增刪改查)一.什么是Linq(what). ...

  9. python lamba表达式

    lambda函数也叫匿名函数,即,函数没有具体的名称. g=lambda x:x**2 def f(x): return x**2 lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边是 ...

随机推荐

  1. android 开发 View _10_ Path之基本操作

    转载地址:http://www.gcssloop.com/customview/Path_Basic/ 安卓自定义View进阶-Path之基本操作 在上一篇Canvas之图片文字中我们了解了如何使用C ...

  2. selenium:chromedriver与chrome版本对应关系

    1.chromedriver下载地址:http://npm.taobao.org/mirrors/chromedriver 2.谷歌浏览器与chromedriver的版本对应关系,供参考: Chrom ...

  3. I2C的小结

    下面是 I 2 C 总线的一些特征 只要求两条总线线路 一条串行数据线 SDA 一条串行时钟线 SCL 每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机 从机关系软件设定地 址 主机可以 ...

  4. Delphi使用逍遥安卓模拟器

    由于使用红鱼儿推荐的iTools安卓模拟器一打开virtualbox就消失,所以自己琢磨了使用逍遥安卓 首先在软件管理里面下载逍遥安卓,然后安装设置一下: 3.安装并启动虚拟机,Delphi IDE是 ...

  5. setTimeout应用例子-移入移出div显示和隐藏

    效果:移入div1,div2保持显示,移出div1,div2消失. 移入div2,div2保持显示,移出div2,div2消失. 一.HTML代码 <div id='div1'></ ...

  6. CSS: pseudo-classes and pseudo-elements

    1.Definition: pseudo-classes The pseudo-class concept is introduced to permit selection based on inf ...

  7. 29.Hibernate-二级缓存和session管理.md

    目录 1.概念 1.1一级缓存: 1.2二级缓存: 2.使用方法 3.策略 3.1缓存策略 3.2集合缓存 3.3查询缓存 5. Seesion管理 1.概念 Hibernate提供的缓存 有一级缓存 ...

  8. postgres on linux red hat 7 配置问题

    记录几个重点的东西吧,具体的步骤 不上了,网上有很多, 1.  redhat subscripiton需要订阅,没钱的需要去更换yum 源,也很简单,就是把自带的yum给删掉,重装其他的,大家可以百度 ...

  9. 吴裕雄 python深度学习与实践(15)

    import tensorflow as tf import tensorflow.examples.tutorials.mnist.input_data as input_data mnist = ...

  10. mongodb安装及配置

    下载安装篇 MongoDB 提供了 linux 各发行版本 64 位的安装包,你可以在官网下载安装包. 下载地址:https://www.mongodb.com/download-center#com ...