C++17 lambda 捕获 *this

C++17 lambda capture *this

提问人:bolov 提问时间:1/13/2017 最后编辑:Toby Speightbolov 更新时间:1/29/2019 访问量:5391

问:

C++17 将按值添加此对象的复制捕获捕获规范为 [*this]。

这有什么用?它与捕获有何不同?这难道不能在 C++14 中实现吗?this[tmp = *this]


解释为什么P0018R3使用而不是在他们的例子中。如果他们使用了 ,C++14 解决方案的所有列出的缺点都将被消除。[=, tmp = *this][tmp = *this][tmp = *this]

C Lambda ++17 C ++-常见问题

评论

4赞 dyp 1/13/2017
我想他们把例子简化得太简单了。添加其他局部变量或参数后,需要通过复制来捕获它们。然后,该部分就有意义了(如果您不想逐个明确捕获它们,那就是)。[=, ..]
0赞 curiousguy 1/26/2019
在非静态成员函数和其他函数之间进行类比可能会有所帮助,甚至在 C++ 和 C++ 之间,如果在“带类的 C”的历史中,引用先于成员函数(只是指针,因为它被发明时没有引用)。this

答:

5赞 Richard Hodges 1/13/2017 #1

想象一下,这是一个句柄类,它维护某种共享状态。*thisshared_ptr

例如,共享 impl 是一个协议处理程序状态机。

句柄类通过一系列异步处理程序传递,因此其本身必须是可复制的。每个处理程序都会改变共享状态。

一个强大的用例可能是用于自定义服务的协议处理程序(例如,)。asiohttp_protocol_socket

[=, tmp = *this]将按值混杂捕获任何变量,包括指针本身,以及专门捕获到 .this*thistmp

在此用例中,无意中在异步处理程序中引用会很危险,因为它很可能是一个悬空指针。这是一个等待发生的错误。this

[tmp=*this]只会捕获.*this

34赞 Toby Speight 1/13/2017 #2

它有什么用?当您需要 的副本时,它很有用 - 例如,当它在计算 lambda 时本身不再有效时。*this*this

它与捕获有何不同?它创建对象的副本,因此在计算 lambda 时,其指针引用副本,而不是原始对象。thisthis

它可以在 C++14 中实现吗?它可以,但更方便,因为可以移动代码,而无需在成员访问前面加上 。否则,尤其是当 时,当您打算引用副本时,可能会意外地引用原始对象的成员(特别是如果您习惯于剪切 + 粘贴编程)。 在这种情况下,是一个更安全的替代方案,因为原始对象无法从 lambda 的主体内部访问(至少,不能通过指针访问)。[tmp = *this][*this]tmp.[=, tmp = *this][=,*this]this

评论

0赞 curiousguy 1/26/2019
this是标量右值,因为第一个“严肃”的 C++(只有在原始 C++ 中它是可赋值的),你不能引用对象,只能引用 的值。thisthis
0赞 Toby Speight 1/28/2019
@curiousguy,我不确定你在这里的批评是什么。我是否在某处对术语含糊不清?我看到我在谈论时写了“(原始)对象”——这会给你带来问题吗?*this
0赞 curiousguy 1/29/2019
没有指针的原始值这样的东西;指针值是指针值是指针值。“原来的这个”毫无意义。
0赞 Toby Speight 1/29/2019
谢谢@curiousguy,我想我现在明白你的意思了。我会试着想出一种更清晰的方式来表达我的意思。(时间流逝)。更好?