尊敬的stackoverflow社区!
最近,我正在寻找工作中的错误,这使我进入了自己编写的以下代码。这是一个简化的版本:
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框架中的插槽)
这是我的期望:
但是,我错了。使用GCC 9.3.0编译后,我得到以下输出:
1
1
1
1
1
这是否意味着对于循环的每次迭代都创建1个“隐藏”仿函数(然后在循环的第一次迭代期间初始化静态变量)?这是否意味着我们应该避免在lambda中使用讨厌的non-constexpr静态变量?我在哪里错了?
感谢您的时间,期待您的答复。
答案 0 :(得分:7)
可以将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表达式主体中的任何本地静态数据只不过是成员函数中的本地静态数据-且仅初始化一次。两种情况下的行为相同是一件好事,以不同的方式处理可能会造成混乱。