请参阅以下代码:
std::function<int(int)> makeFibonacci() {
std::function<int(int)> fibonacci = [&fibonacci](int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
return fibonacci(n-1) + fibonacci(n-2);
};
return fibonacci;
};
int main() {
std::function<int(int)> fibonacci = makeFibonacci();
std::cout << fibonacci(6) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,数字8按预期输出.但是,当我将捕获更改&fibonacci为仅fibonacci用于副本捕获时,程序实际上会main在其运行的第一行上进行段错误makeFibonacci.
如果fibonacci(第2行)是makeFibonacci函数的局部函数,因此当函数退出时超出范围,如何通过引用捕获并递归使用?另外,为什么当我通过副本捕获lambda时程序会出现段错误?
Cur*_*ous 12
如果fibonacci(第2行)是
makeFibonacci()函数的局部函数,因此当函数退出时超出范围,如何通过引用捕获并递归使用?
这是函数按预期工作的机会.你有什么是未定义的行为.您正在引用超出函数范围的对象.
另外,为什么当我通过副本捕获lambda时程序会出现段错误?
这是因为std::function初始化的原因.lambda首先std::function被初始化,然后用lambda初始化.这意味着您正在复制std::function未初始化的实例,因此它可能不处于允许良好副本的状态.不变量在内部被破坏,这可能导致分段错误.
您可以更高效地创建递归lambda函数,而无需std::function使用多态lambda,如下所示
auto makeFibonacci() {
auto fib = [](int n, auto& self) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 1;
}
return self(n - 1, self) + self(n - 2, self);
};
return [fib](int n) {
return fib(n, fib);
};
};
Run Code Online (Sandbox Code Playgroud)
lambda 拥有它所需要的所有状态.然后你可以像这样使用它
auto fibonacci = makeFibonacci();
cout << fibonacci(6) << endl;
Run Code Online (Sandbox Code Playgroud)
另请注意,这可能是计算斐波纳契数的最差方法.