c++ - 如果 lambda 在运行时被移动/破坏会发生什么?

标签 c++ c++11 lambda undefined-behavior

考虑:

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/31493761/

相关文章:

c++ - 我的 vector vector 有什么问题?

c++ - 为什么使用 std::forward 禁用模板参数推导?

c++ - 如何使用命名变量为 const 右值引用参数定义默认值?

java - 阻止访问自己类中的特定属性

javascript - Webpack 和 AWS Lambda 问题 - 模块上缺少处理程序

c++ - 有什么方法可以初始化 unique_ptr 的 vector 吗?

c++ - 在 GNU 的 C++ 代码中使用 C 头文件。包含内联程序集 : impossible constraint in 'asm' 的错误

c++ - 分配大的静态 std::unordered_map 导致堆栈溢出

c# - 编译器未解析为预期的扩展方法

c++ - 全局变量在不同的静态方法中使用时会得到不同的值