C++ std::function 导致段错误

wan*_*907 1 c++

谁能告诉我为什么下面的代码会导致段错误?奇怪的是调用函数没问题f3,但是调用函数f4会导致段错误。

如果我在引用中使用捕捉ComposableFunction,都f3f4做工精细...

#include <functional>
#include <iostream>

using namespace std;

template<typename T, typename R>
struct ComposableFunction {
    std::function<R(T)> func;

    template<typename O>
    ComposableFunction<T, O> then(std::function<O(R)> thenFunc) {
        return {[=](T t) -> O { return thenFunc(func(t)); }};
    }
};

int plus99(int i) {
    return i + 99;
}

int main() {
    ComposableFunction<int, int> f0 {&plus99};
    std::function<int(int)> f3 = f0.then<int>(&plus99).then<int>(&plus99).func;
    cout << f3(1999) << endl;  // this line is ok
    std::function<int(int)> f4 = f0.then<int>(&plus99).then<int>(&plus99).then<int>(&plus99).func;
    cout << f4(1999) << endl;  // this line will lead to a segment fault
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Hol*_*Cat 5

这是一个不错的。您的代码*this通过引用捕获,并且该引用很快变得悬而未决。

如果我在引用中使用捕捉ComposableFunction,都f3f4做工精细

这会导致更多对 dangle 的引用,因此这不是解决方案。

GCC 用 警告了这一点-Wall -Wextra,但没有很好地解释它。Clang 需要-Wdeprecated,但会产生更好的警告:

warning: implicit capture of 'this' with a capture default of '=' is deprecated [-Wdeprecated-this-capture]
note: add an explicit capture of 'this' to capture '*this' by reference
Run Code Online (Sandbox Code Playgroud)

它告诉您您正在有效地捕获this,即通过引用当前对象。

修复方法是显式捕获*this,以制作副本。请注意*.

此外,我会thenFunc通过写入thenFunc = std::move(thenFunc)捕获列表来明确进入 lambda 。因为否则它会被复制。