静态变量如何直接在lambda体中使用,甚至调用超出静态变量的范围

时间:2014-11-04 02:46:29

标签: c++ lambda

我在阅读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函数之外存活? 一般来说,你不能引用一个局部的静态变量而不是它。“

2 个答案:

答案 0 :(得分:3)

lambdas的规则规定,您不能在所述实体的生命周期内使用任何捕获的实体。

具有静态生命周期的对象的生命周期直到main()结束(或调用exit())。因此在返回lambda后使用它没有问题。只有在具有静态生命周期的其他对象(例如全局变量)的析构函数中使用才可能成为问题。

事实上,这个变量甚至没有被lambda捕获。没有必要,就像没有必要捕获全局变量一样。它的工作原理是因为lambda中的标识符查找在封闭范围内找到具有静态生存期的对象,因此它会被使用。由于变量没有自动存储持续时间,因此不会触发隐式捕获的规则。

这是规则,从5.1.2开始:

  

具有关联 capture-default 的lambda表达式,它不显式捕获this或具有自动存储持续时间的变量(这不包括任何 id-expression 已经发现它指的是 init-capture 的相关非静态数据成员),据说隐式捕获实体(即{{1} }或变量)如果复合语句

     
      
  • odr-uses(3.2)实体,或
  •   
  • 在封闭的full-expression所依赖的潜在评估表达式(3.2)中命名实体   在 lambda-expression 的到达范围内声明的通用lambda参数上。
  •   

捕获机制的全部原因是lambda可以定位它使用的变量,如果这些变量具有时变位置。静态变量(以及全局变量,静态类成员和函数,以及其他任何不是自动局部变量或this的非静态数据成员)都不会四处移动,因此将它们的位置固定在lambda对象不是必需的。

简而言之:您绝对可以继续使用范围之外的静态本地。许多标准库函数都以这种方式工作,例如this。范围确定名称是否被识别;对于具有静态或动态生命周期的对象,范围对生命周期没有影响。

答案 1 :(得分:0)

enter image description here

lambda住在returnLambda里面,这是你要问的吗? &GT;&LT;