谁能告诉我为什么下面的代码会导致段错误?奇怪的是调用函数没问题f3,但是调用函数f4会导致段错误。
如果我在引用中使用捕捉ComposableFunction,都f3和f4做工精细...
#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)
这是一个不错的。您的代码*this通过引用捕获,并且该引用很快变得悬而未决。
如果我在引用中使用捕捉
ComposableFunction,都f3和f4做工精细
这会导致更多对 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 。因为否则它会被复制。