- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在阅读 lambda 的局部静态变量捕获规则时,我感到困惑,请参见以下代码:
std::function<bool(int)> returnLambda()
{
static int s_b = 1;
return [](int a){return a+s_b ;} ;
}
int main()
{
int i;
i = returnLambda()(2);
return i;
}
在returnLambda函数中,当lambda表达式求值时,构造一个函数对象并返回。然后在调用处有一个拷贝,在调用处调用operator(),局部静态变量也是如此。这里的问题是,为什么returnLambda函数内部的局部静态变量在returnLambda函数外部仍然可以存活?通常你不能引用一个局部静态变量,因为它是正常的。
最佳答案
lambda 规则规定您不能在所述实体的生命周期之外使用任何捕获的实体。
具有静态生命周期的对象的生命周期直到 main()
结束(或调用 exit()
)。所以返回lambda后使用是没有问题的。只有在具有静态生命周期的其他对象(例如全局对象)的析构函数中使用才可能成为问题。
事实上,这个变量甚至没有被 lambda 捕获。不需要,就像不需要捕获全局变量一样。它之所以有效,是因为 lambda 中的标识符查找在封闭范围内找到了一个具有静态生命周期的对象,因此它被使用了。由于该变量没有自动存储期限,因此不会触发隐式捕获规则。
这是规则,来自 5.1.2:
A lambda-expression with an associated capture-default that does not explicitly capture
this
or a variable with automatic storage duration (this excludes any id-expression that has been found to refer to an init-capture's associated non-static data member), is said to implicitly capture the entity (i.e.,this
or a variable) if the compound-statement:
- odr-uses (3.2) the entity, or
- names the entity in a potentially-evaluated expression (3.2) where the enclosing full-expression depends on a generic lambda parameter declared within the reaching scope of the lambda-expression.
捕获机制的全部原因是 lambda 可以定位它使用的变量,如果这些变量具有随时间变化的位置。静态变量(以及全局变量、静态类成员和函数,以及任何其他不是自动局部变量或 this
的非静态数据成员的东西)不会四处移动,所以坚持他们的lambda 对象中的位置不是必需的。
简而言之:您绝对可以继续在其范围之外使用静态局部变量。许多标准库函数以这种方式工作,例如 asctime
。范围决定名称是否被识别;对于具有静态或动态生命周期的对象,作用域对生命周期没有影响。
关于c++ - 即使调用超出静态变量的范围,如何在lambda的主体中直接使用静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26726920/
我是一名优秀的程序员,十分优秀!