You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

调用指向已销毁Lambda的指针是否合法?含带捕获Lambda的通用场景

调用指向已超出作用域Lambda的指针是否合法?

无捕获Lambda的情况

你的示例代码中使用的是无捕获的Lambda,这种情况是合法的。

C++标准规定,无捕获的Lambda可以隐式转换为同签名的普通函数指针。这类Lambda的函数体本质上是全局可见的代码片段,和普通全局函数的存储方式类似——即使Lambda变量(lambda)超出作用域被销毁,函数指针(fun)指向的代码依然存在且有效。所以调用fun(6)是完全合规的,不会触发未定义行为。

带捕获Lambda的情况

如果是带有捕获的Lambda,情况就完全不同了:

  • 带捕获的Lambda无法隐式转换为普通函数指针,因为它的行为依赖于捕获的变量(闭包状态),必须通过闭包对象来调用其operator()成员函数。
  • 若你持有指向闭包对象的指针/引用,当闭包对象(即Lambda变量)超出作用域被销毁后,这个指针就变成了悬垂指针。此时通过该指针调用Lambda的行为属于未定义行为——无论捕获的是值还是引用:
    • 即使是值捕获,闭包对象销毁后,其内部存储的捕获值也会被释放,访问已销毁对象的成员函数会导致不可预料的结果;
    • 引用捕获的话,捕获的外部变量本身已经超出作用域,调用Lambda时访问该引用同样是未定义行为。

示例说明(带捕获Lambda的非法场景)

#include <iostream>
#include <functional>

int main()
{
    std::function<int(int)> fun;
    int* lambda_ptr = nullptr;

    {
        int x = 10;
        auto lambda = [x](int a)->int{std::cout << a + x << std::endl; return a + x;};
        fun = lambda; // std::function保存闭包对象拷贝,后续调用合法
        lambda_ptr = reinterpret_cast<int*>(&lambda); // 指向闭包对象的指针
    }

    // 若通过lambda_ptr调用原Lambda,属于访问已销毁对象,是未定义行为
}

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 10:43:15