8
#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

在此先感谢,如果以前回答过这个问题,我很抱歉(我确实试图找到类似的问题但没有成功)

4

2 回答 2

4

这是未定义的行为

根据 C++11 标准的第 5.2.2/4 段关于函数调用表达式及其参数的初始化:

[...]参数的生命周期在定义它的函数返回时结束。每个参数的初始化和销毁​​发生在调用函数的上下文中。[...]

因此,您的 lambda 将存储一个引用,该引用会在函数调用返回时立即悬空。

在这种情况下,实现可以自由(并且可能)为每个函数调用在同一地址创建函数参数,这可能是您观察预期输出的原因。

但是,此行为不是标准强制要求的 - 因此,您不应依赖它(如果是这种情况,您的代码将是合法的,因为 3.8/7)。

于 2013-04-17T22:18:43.003 回答
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);
}
于 2013-04-17T22:24:06.063 回答