gpt4 book ai didi

c++ - Lambda捕获范围

转载 作者:行者123 更新时间:2023-12-02 09:58:11 25 4
gpt4 key购买 nike

我正在努力了解lambda捕获的范围和所有权,以下代码为何起作用?:

#include <iostream>

struct Foo {
void setCallback(std::function<void()> f) { callback = std::move(f); }

void trigger() { callback(); }

private:
std::function<void()> callback;
};

struct Bar {
int i;

Bar(int i) : i{i} { std::cout << "bar constructed" << std::endl; }

~Bar() { std::cout << "bar destroyed" << std::endl; }
};

int main() {
Foo foo{};

{ // scope
Bar bar{1};
foo.setCallback([&bar]() { std::cout << bar.i << std::endl; });
bar.i = 2;
} //end of scope, bar gets deleted

foo.trigger();
return 0;
}

输出:
bar constructed 
bar destroyed
2
编译器是否在lambda函数中静态内联 bar.i?我正在通过引用捕获,这是怎么回事?

最佳答案

您好,您的代码无法正常工作,因为bar在执行捕获它的lambda之前已被取消作用域。 Lambda使用悬空引用。这是一个经过更新的示例,可以说服您,如果它在您的示例中起作用,那仅仅是因为没有其他任何东西被分配到最初存储bar的地址。

#include <iostream>
#include <functional>

struct Foo {
void setCallback(std::function<void()> f) { callback = std::move(f); }

void trigger() { callback(); }

private:
std::function<void()> callback;
};

struct Bar {
int i;

Bar(int i) : i{i} { std::cout << "bar constructed" << std::endl; }

~Bar() { std::cout << "bar destroyed" << std::endl; }
};

int main() {
Foo foo{};

{ // scope
Bar bar{1};
foo.setCallback([&bar]() { std::cout << bar.i << std::endl; });
bar.i = 2;
} //end of scope, bar gets deleted

volatile int a = 5; // allocate something after bar is destroyed

foo.trigger();
return 0;
}
现在您将获得:
bar constructed 
bar destroyed
5
5是在堆栈上代替bar分配的下一个值。

关于c++ - Lambda捕获范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64228393/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com