C ++ 17 lambda capture * this

时间:2017-01-13 14:59:26

标签: c++ lambda c++17 c++-faq

C ++ 17将使用a capture specification of [*this]按值添加此对象的复制捕获

这有用吗?它与捕获this有什么不同?使用[tmp = *this]

在C ++ 14中是否已经无法实现这一点

用于解释为什么P0018R3在其示例中使用[=, tmp = *this]代替[tmp = *this]的奖励。如果他们使用了[tmp = *this],那么所有列出的C ++ 14解决方案的缺点都将被消除。

2 个答案:

答案 0 :(得分:28)

它有用吗?当您需要*this的副本时,它非常有用 - 例如,当this本身在评估lambda时不再有效时。

与捕获this有什么不同?它生成对象的副本,因此在评估lambda时,其[tmp = *this]指针指的是副本,而不是原始对象。

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

答案 1 :(得分:4)

想象一下,*this是一个句柄类,它保持shared_ptr到某个共享状态。

共享impl是(例如)协议处理程序状态机。

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

强大的用例可能是与自定义asio服务一起使用的协议处理程序(例如,http_protocol_socket)。

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

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

[tmp=*this]只会抓取*this