C++17 lambda 捕获 *this

C++17 lambda capture *this

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

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


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

假设 *this 是一个句柄 class,它维护 shared_ptr 到某个共享状态。

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

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

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

[=, tmp = *this] 将通过值混杂地捕获任何变量,包括相当危险的 this 指针本身,以及专门将 *this 捕获到 tmp.

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

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

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

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

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