C++ lambda 生命周期

C++ lambda lifecycle

本文关键字:周期 生命 lambda C++      更新时间:2023-10-16

在下面的代码中,运行时会发生什么?

while ( ([]()->bool { return something(); })() ) {
...
}
  1. lambda 实例仅创建一次,并在后续迭代中重复使用。
  2. 每次迭代都会创建一个新实例,该实例仅使用一次。
  3. 以上都不是(请解释)。

最初对我来说很明显,它在每次迭代中都会重新创建,但我想知道编译器是否进行了某种优化。

首先是几个标准引号,我的重点是:

[标准同时]/1

在 while 语句中,子语句重复执行,直到 条件的值 ([stmt.select]) 变为 false。测试内容 在每次执行子语句之前发生

[expr.prim.lambda]/2

lambda 表达式是一个 prvalue,其结果对象称为 闭包对象。

上面告诉 USE 在每次迭代之前都会评估([]()->bool { return something(); })()。并且子表达式[]()->bool { return something(); }创建一个 prvalue。因此,只有在评估完整表达时,它才会栩栩如生。

因此,法律的干巴巴的文字表明它是闭包类型的不同对象,每次评估条件时都会被构建和破坏。

但编译器并不愚蠢。我相信,在 as-if 规则下,它很可能会被优化为对something()的直接调用。这是因为 lambda 的构建和破坏没有可观察到的副作用。

如果我们确实使用像godbolt在线编译器查看器这样的工具,我们看到GCC 7.2 at-O1将直接调用该函数。Clang 5.0也是如此,但我必须进行优化才能-O2实现这一目标。