热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[C++]lambdacapture的成员函数异步调用

关于lambdacapture:Ifthecapture-defaultis&,subsequentsimplecapturesmustnotbeginwith&.

关于lambda capture:

If the capture-default is &, subsequent simple captures must not begin with &.

struct S2 { void f(int i); };
void S2::f(int i)
{[&]{}; // OK: by-reference capture default[&, i]{}; // OK: by-reference capture, except i is captured by copy[&, &i] {}; // Error: by-reference capture when by-reference is the default[&, this] {}; // OK, equivalent to [&][&, this, i]{}; // OK, equivalent to [&, i]
}

If the capture-default is =, subsequent simple captures must begin with & or be *this (since C++17) or this (since C++20).

struct S2 { void f(int i); };
void S2::f(int i)
{[=]{}; // OK: by-copy capture default[=, &i]{}; // OK: by-copy capture, except i is captured by reference[=, *this]{}; // until C++17: Error: invalid syntax// since c++17: OK: captures the enclosing S2 by copy[=, this] {}; // until C++20: Error: this when = is the default// since C++20: OK, same as [=]
}

Any capture may appear only once:

struct S2 { void f(int i); };
void S2::f(int i)
{[i, i] {}; // Error: i repeated[this, *this] {}; // Error: "this" repeated (C++17)
}

如果lambda capture的是成员函数,这个lambda在它所capture的类对象释放后异步调用:

class A:
{
public:int func(){std::ofstream myfile("example.txt");if (myfile.is_open()){myfile <<"Write from child thread.\n";myfile.close();}else{std::cout <<"Unable to open file";}}void detach(){std::thread t([this]() {std::this_thread::sleep_for(std::chrono::milliseconds(3000));func();});t.detach();}
};int main()
{{A a;a.detach();}std::cout <<"main end" <}

当main函数执行到打印“main end”时&#xff0c;a对象已经释放&#xff0c;但是它创建的子线程中调用了它的成员函数依然可以正常执行。这是因为成员函数在转变为汇编代码时与普通的函数一样&#xff0c;只不过会将this指针作为它的第一个参数传入&#xff0c;而且a对象的func()方法中没有调用A的其他成员变量&#xff0c;因此不会发生crash。正确的写法应该是在进入lambda的时候判断此时它capture的this指针所指向的对象是否还是有效的&#xff1a;

#define RETURN_FROM_LAMBDA_IF_DEAD(x) \auto sharedThis &#61; x.lock(); \if(!sharedThis) \return;class A: public std::enable_shared_from_this
{
public:int func(){std::ofstream myfile("example.txt");if (myfile.is_open()){myfile <<"Write from child thread.\n";myfile.close();}else{std::cout <<"Unable to open file";}}void detach(){std::thread t([weakThis &#61; weak_from_this(), this]() {RETURN_FROM_LAMBDA_IF_DEAD(weakThis);std::this_thread::sleep_for(std::chrono::milliseconds(3000));func();});t.detach();}
};int main()
{{A a;a.detach();}std::cout <<"main end" <}

另外&#xff0c;如果确实想要在lambda中调用this指向对象的成员函数且这个成员函数没有调用成员变量&#xff0c;可以把这个成员函数定义成private static&#xff0c;这样就不会有上面说的问题。

 

参考链接&#xff1a;

https://en.cppreference.com/w/cpp/language/lambda

https://stackoverflow.com/questions/57654701/member-function-captured-by-lambda-asynchronously-dispatch-issue


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • 本文介绍了在Cpp中将字符串形式的数值转换为int或float等数值类型的方法,主要使用了strtol、strtod和strtoul函数。这些函数可以将以null结尾的字符串转换为long int、double或unsigned long类型的数值,且支持任意进制的字符串转换。相比之下,atoi函数只能转换十进制数值且没有错误返回。 ... [详细]
  • 本文介绍了在go语言中利用(*interface{})(nil)传递参数类型的原理及应用。通过分析Martini框架中的injector类型的声明,解释了values映射表的作用以及parent Injector的含义。同时,讨论了该技术在实际开发中的应用场景。 ... [详细]
  • 本文整理了Java中java.lang.NoSuchMethodError.getMessage()方法的一些代码示例,展示了NoSuchMethodErr ... [详细]
  • tcpdump 4.5.1 crash 深入分析
    tcpdump 4.5.1 crash 深入分析 ... [详细]
  • 本文整理了Java中org.gwtbootstrap3.client.ui.Icon.addDomHandler()方法的一些代码示例,展示了Icon.ad ... [详细]
  • 我用Tkinter制作了一个图形用户界面,有两个主按钮:“开始”和“停止”。请您就如何使用“停止”按钮终止“开始”按钮为以下代码调用的已运行功能提供建议 ... [详细]
author-avatar
手机用户2602901497
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有