#include <iostream>
void foo(int k) {
static auto bar = [&]{
std::cout << k << std::endl;
};
bar();
}
int main () {
foo(1); foo(2); foo(3); // output is correct: 1, 2, 3
}
检查函数 foo ,静态lambda如何通过引用捕获 k 。这似乎有效,并且更复杂的数据类型而不是 int 也会发生同样的情况。
这是预期的吗? 是否保证每次调用 foo 时 k 的地址都相同,或者 UB ?
提前致谢,如果之前已经回复,我很抱歉(我确实试图找到类似的问题而没有成功)
答案 0 :(得分:4)
这是未定义的行为。
关于函数调用表达式及其参数初始化的C ++ 11标准的第5.2.2 / 4节:
[...] 参数的生命周期在它所在的函数结束时 是定义的回报。每个参数的初始化和销毁都发生在上下文中 调用功能。 [...]
因此,一旦函数调用返回,你的lambda将存储一个变为悬空的引用。
在这种情况下,实现是免费的(并且可能)在每个函数调用的同一地址创建函数参数,这可能是您观察预期输出的原因。
但是,标准没有规定这种行为 - 因此,你不应该依赖它(如果是这种情况,你的代码将因为3.8 / 7而合法)。
答案 1 :(得分:1)
在你的例子中它可能“正常工作”的原因是调用堆栈总是以相同的方式排列。试试这个,看看你是否仍然得到“预期”的输出。
#include <iostream>
void foo(int k) {
static auto bar = [&]{
std::cout << k << std::endl;
};
bar();
}
void baz(int k) {
std::cout << "baz: ";
foo(k);
}
int main () {
foo(1); baz(2); foo(3);
}