C++17 λ捕获*这个

C++17 lambda capture *this

本文关键字:这个 捕获 C++17      更新时间:2023-10-16

C++17 将按值添加此对象的副本捕获,捕获规范为 [*this]

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


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

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

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

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

假设*this是一个句柄类,它维护对某些共享状态的shared_ptr

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

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

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

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

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

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