gpt4 book ai didi

c++ - 如果 lambda 在运行时被移动/销毁会怎样?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:20:59 24 4
gpt4 key购买 nike

考虑:

std::vector<std::function<void()>> vec;
something_unmovable m;
vec.push_back([&vec, m]() {
vec.resize(100);
// things with 'm'
});
vec[0]();

vec.resize(100) 可能会导致 vector 的重新分配,这意味着 std::function 将被复制到新位置,旧的被摧毁了。然而,这发生在旧版本仍在运行时。此特定代码运行是因为 lambda 不执行任何操作,但我想这很容易导致未定义的行为。

那么,到底发生了什么? m 是否仍然可以从 vector 访问?还是 lambda 的 this 指针现在无效(指向已释放的内存),因此无法访问 lambda 捕获的任何内容,但如果它运行的代码不使用它捕获的任何内容,这不是未定义的行为?

此外,lambda 可移动的情况有什么不同吗?

最佳答案

正如其他答案已经涵盖的那样,lambda 本质上是语法糖,用于轻松创建提供自定义 operator() 实现的类型。这就是为什么您甚至可以使用对 operator() 的显式引用来编写 lambda 调用,如下所示:int main() { return [](){ return 0; }。运算符(operator)()(); }。所有非静态成员函数的相同规则也适用于 lambda 主体。

并且这些规则允许在执行成员函数时销毁对象,只要成员函数之后不使用 this 即可。你的例子是一个不寻常的例子,更常见的例子是一个非静态成员函数执行 delete this;This made it into the C++ FAQ ,解释说这是允许的。

据我所知,该标准通过不真正解决它来允许这一点。它以不依赖于对象未被销毁的方式描述成员函数的语义,因此实现必须确保让成员函数继续执行,即使对象被销毁。

所以回答你的问题:

Or is it that the this pointer of the lambda is now invalid (points to freed memory), so nothing the lambda captures can be accessible, yet if it runs code that doesn't use anything it captures, it's not undefined behavior?

是的,差不多。

Also, is the case where the lambda is movable any different?

不,不是。

唯一可能影响 lambda 移动的时间是在移动 lambda 之后。在您的示例中,operator() 继续在原始移出然后销毁的仿函数上执行。

关于c++ - 如果 lambda 在运行时被移动/销毁会怎样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49793550/

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