lambda 捕获的对象是否与 lambda 一样存在?

Ann*_*inn 2 c++ lambda multithreading

我一直认为 lambda 只是函数指针,但我从未想过认真使用 capture 语句......

如果我创建一个通过副本捕获的 lambda,然后将该 lambda 移动到完全不同的线程,并且不尝试保存 lambda 中使用的原始对象,它会为我保留这些副本吗?

std::thread createThread() {
    std::string str("Success");
    auto func = [=](){ 
        printf("%s", str.c_str());
    };
    str = "Failure";
    return std::thread(func);
}

int main() {
    std::thread thread = createThread();
    thread.join();  
    // assuming the thread doesn't execute anything until here...
    // would it print "Success", "Failure", or deference a dangling pointer?
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

use*_*522 5

保证打印Success。按副本捕获正如它所说的那样。它在那里复制该对象并将该副本存储为闭包对象的一部分。从捕获创建的闭包对象的成员与闭包对象本身的生命周期一样长。

lambda 不是函数指针。Lambda 是通用函数对象,可以具有函数指针所没有的内部状态。事实上,只有无捕获的 lambda 表达式才能转换为函数指针,因此有时可能表现得像函数指针。

lambda 表达式生成一个闭包类型,基本上如下所示:

struct /*unnamed1*/ {
    /*unnamed1*/(const /*unnamed1*/&) = default;  
    /*unnamed1*/(/*unnamed1*/&&) = default;           

    /*unnamed1*/& operator=(const /*unnamed1*/&) = delete;       

    void operator()() const {
        printf("%s", /*unnamed2*/.c_str());
    };

    std::string /*unnamed2*/;  
};
Run Code Online (Sandbox Code Playgroud)

并且 lambda 表达式生成此类型的对象,并/*unnamed2*/直接初始化为 的当前值str。(直接初始化的含义如同std::string /*unnamed2*/(str);