C++ lambda捕获寿命

C++ lambda捕获寿命,c++,lambda,C++,Lambda,鉴于以下计划: #include <iostream> #include <memory> using namespace std; int main() { std::shared_ptr<int> i(new int(42)); cout << i.use_count() << endl; auto fn = [=](){i; cout << 42 << endl;}; cou

鉴于以下计划:

#include <iostream>
#include <memory>
using namespace std;
int main() {
    std::shared_ptr<int> i(new int(42));
    cout << i.use_count() << endl;
    auto fn = [=](){i; cout << 42 << endl;};
    cout << i.use_count() << endl;
    return 0;
}
#包括
#包括
使用名称空间std;
int main(){
标准::共享ptr i(新int(42));

cout如果我们转到上的参考页,他们有以下解释:

[=]按值捕获lambda主体中提到的所有自动变量

并进一步表示:

捕获列表是以逗号分隔的零个或多个捕获的列表,可以选择以捕获默认值开头。唯一的捕获默认值是&(隐式捕获odr使用的自动变量,此为引用)和=(隐式捕获odr使用的自动变量,此为按值)。

参考部分说明:

如果变量的名称显示为一个可能的求值表达式,则使用odr,除非以下所有条件都是 正确:

  • 将左值到右值的转换应用于表达式会生成一个不调用非平凡函数的常量表达式
  • 表达式是丢弃的值表达式或左值到右值的转换
异常不适用于
i
,因此将捕获
i

这与
5.1.2节
Lambda表达式第11段一致,其中规定:

如果lambda表达式具有关联的捕获默认值及其 复合语句odr使用(3.2)this或带有自动 未显式捕获存储持续时间和odr使用的实体, 然后,odr使用的实体被称为隐式捕获;例如 实体应在lambda的范围内申报 表情


默认捕获为
[=]
,如果在lambda中使用odr,则捕获任何局部变量。使用的odr定义为:

如果变量的名称显示为可能的求值表达式,则使用odr,除非它是满足在常量表达式中出现的要求的对象,并且立即应用左值到右值的转换

这里,
i
是一个经过计算的表达式,不是常数;因此它是
odr used
,因此被捕获;无论对表达式进行计算是否有任何效果

但这有标准保证吗

是的