下面的代码工作正常:
#include <iostream>
#include <functional>
std::function<int (void)> get_incrementer() {
return []() {
static int count = 0;
return count++;
};
}
int main() {
using std::cout;
auto incrementer = get_incrementer();
cout << incrementer() << std::endl;
cout << incrementer() << std::endl;
return 0;
}
但是如果您改为通过引用捕获局部变量,它会突然导致未定义的行为,大概是因为在调用时堆栈上的那个位置正被其他东西使用。
std::function<int (void)> get_incrementer() {
int count = 0;
return [&count]() {
return count++;
};
}
为什么编译器允许它呢?我希望编译器要么不允许这样做(检查这种情况似乎微不足道),要么更改局部变量的存储持续时间。
最佳答案
C++ 允许这样做,因为 C++ 不是一种安全 语言。虽然这种情况可能是“微不足道的”检查(就我个人而言,我不同意它是微不足道的,但我不是编译器编写者),还有很多其他情况不是 检查起来很简单。
C++ 不会为您修复损坏的代码。它完全按照您的指示去做,即使它非常不明智。
此外,您并不完全清楚您打算让这段代码做什么。例如,这是两个完全不同的东西:
std::function<int (void)> get_incrementer() {
return []() {
static int count = 0;
return count++;
};
}
std::function<int (void)> get_incrementer() {
int count = 0;
return [count]() mutable {
return count++;
};
}
在第一种情况下,返回函数的每个实例将共享相同的增量计数。在第二种情况下,每次您调用 get_incrementer
时,您都会获得一个单独的对象及其自己的增量计数。
用户想要哪一个?目前还不清楚。所以你不能随便“纠正”它。
关于c++ - C++ lambda 中的静态变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16750933/