【问题标题】:Lambda capture 'this' saved as std::functionLambda 捕获 'this' 保存为 std::function
【发布时间】:2018-02-10 01:18:46
【问题描述】:

以下代码使用 C++14 编译正常,但运行它会导致分段错误。这是由 lambda 函数捕获引起的(用问号注释)吗?正确的方法是什么?提前致谢。

#include <functional>
#include <iostream>
#include <memory>

struct Process {
    Process(std::function<void()> &processFunc) 
        : processFunc(processFunc) {}
    void doit() {
        processFunc();  // causes segmentation fault
    }

    std::function<void()> &processFunc;
};

struct Foo {
    Foo() {
        std::function<void()> func = [this](){this->process();}; // ?
        p = std::make_unique<Process>(func);
    }
    void process() {std::cout << "Done.\n";}
    void start() {p->doit();}
    std::unique_ptr<Process> p;
};

int main()
{
    Foo foo;
    foo.start();
}

【问题讨论】:

    标签: c++ c++11 lambda std-function


    【解决方案1】:

    发生分段错误是因为Process::processFunc 所引用的std::function 对象在Foo 构造函数返回时被破坏。要解决此问题,请让Process 保留std::function 对象的副本。

    struct Process {
        Process(const std::function<void()>& processFunc) 
            : processFunc(processFunc) {}
        // ...
        std::function<void()> processFunc;
    };
    

    【讨论】:

    • @ArnavBorborah 是的
    • 好吧,为了完整起见,您可能需要考虑添加这是由您的答案中的悬空引用引起的。
    • @JiveDadson 我不明白五规则在这里是如何应用的。事实上,我会说这是一个“零规则”类。
    • 很公平。我看的不够仔细。我认为构造函数是一个复制构造函数。
    • 太棒了!非常感谢。
    猜你喜欢
    • 2013-12-15
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 2016-04-18
    • 1970-01-01
    • 2017-05-28
    • 2021-05-08
    相关资源
    最近更新 更多