C++ lambda生命周期

kar*_*son 3 c++ lambda

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

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

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

Sto*_*ica 5

首先是几个标准报价,重点是:

[stmt.while]/1

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

[expr.prim.lambda]/2

lambda-expression是一个prvalue,其结果对象称为闭包对象.

上面讲述了([]()->bool { return something(); })()在每次迭代之前评估的用法.并且子表达式[]()->bool { return something(); }创建了一个prvalue.因此,只有在评估完整表达时,它才会生动.

因此,法律的干信表明,每次评估条件时,它都是封闭类型的不同对象,构造和破坏.

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

如果我们确实使用像godbolt在线编译器查看器这样的工具,我们会看到GCC 7.2 -O1将直接调用该函数.Clang 5.0也是如此,但我不得不采取优化措施来-O2实现这一目标.