循环中的Lambda-静态变量

Lambda in for loop - static variable

本文关键字:静态 变量 Lambda- 循环      更新时间:2024-09-21

尊敬的stackoverflow社区!

最近,我在工作中寻找一个bug,这让我找到了下面一段我自己写的代码。这是一个简化版本:

int main()
{
for(int i = 0; i < 5; ++i)
{
int j = i + 1;
auto k = [j](){
static int s{j};
cout << s << endl;
};
k();
}
}

我知道它看起来可能很傻,但它背后有一些逻辑(因为我使用这个lambda连接到QT框架中的一个插槽(

以下是我的期望:

  1. 循环的每次迭代都会创建一个带有函子运算符的新类(因为每次它都捕获新的局部变量(
  2. 静态变量s的初始化将在每次迭代中发生一次,因为它是不同的lambda

然而,我错了。在用GCC 9.3.0编译后,我得到了以下输出:

1
1
1
1
1

这是否意味着1〃;隐藏的";为循环的每次迭代创建一个函子(然后在循环的第一次迭代期间初始化一个静态函数(?这是否意味着我们应该避免在lambdas中使用讨厌的非constexpr静态变量?我哪里错了?

感谢您抽出时间,期待您的回复。

将lambda表达式视为定义重载调用operator()的类的简洁配方。在您的情况下:

struct LambdaEquivalent {
int j;
auto operator() const
{
static int s{j};
cout << s << endl;
}
};

然后你循环就是

for(int i = 0; i < 5; ++i)
{
int j = i + 1;
LambdaEquivalent k{j};
k()
}

这说明lambda表达式主体中的任何局部静态数据都只是成员函数中的局部静态数据,并且只初始化一次。这两种情况表现相同是件好事,不同的处理方式可能会非常令人困惑。