我试图创建一个接受函数向量的compose_all
lambda,并返回一个单个函数,该函数是向量中所有函数的组成:
#include <algorithm>
#include <iostream>
#include <vector>
#include <functional>
using std::cout;
using std::endl;
using std::function;
using std::vector;
int main() {
vector<function<int(int)>> functions = {
[](int x) { return 2 * x; },
[](int x) { return x * x; },
[](int x) { return -x; },
};
function<function<int(int)>(
vector<function<int(int)>>::iterator,
vector<function<int(int)>>::iterator,
function<int(int)>)> compose_all;
compose_all = [&](vector<function<int(int)>>::iterator f_begin,
vector<function<int(int)>>::iterator f_end,
function<int(int)> f) -> function<int(int)> {
for (; f_begin < f_end; ++f_begin) {
f = [&](int x) { return (*f_begin)(f(x)); };
}
return f;
};
auto composition = compose_all(functions.begin(),
functions.end(),
[](int x) { return x; });
for (int i = 0; i < 10; ++i) {
cout << composition(i) << endl;
}
return 0;
}
尽管可以正常编译,但仍会出现以下错误:
$ clang++ -std=c++11 -g composition.cpp && ./a.out
Segmentation fault (core dumped)
造成段错误的原因是什么?解决方法是什么?
使用打印语句和GDB进行调试的注意事项:
compose_all
正确接收了迭代器段故障发生在行
f = [&](int x) { return (*f_begin)(f(x)); };
分别取消引用
f_begin
会产生正确的结果(它在向量中调用正确的lambda) 最佳答案
由创建的每个lambda
f = [&](int x) { return (*f_begin)(f(x)); };
通过引用捕获
f
和f_begin
,其中这两个都是存储在compose_all
中的lambda主体的局部。这些函数中的最后一个在调用时由
compose_all
包含的lambda的正文返回,然后分配给composition
。但是,由于compose_all
的lambda主体已存在,因此f
和f_begin
的生存期已结束,并且调用composition
是未定义的行为。此外,您实际上并不希望
f
自己调用,这只会使您无限递归。您希望f
从其当前值(即初始值,或从您先前分配f
的时间)中调用f
值的副本。您需要类似:
const auto& g = *f_begin;
f = [=](int x) { return g(f(x)); };
(或者在C ++ 14或更高版本中,可以这样写:)
f = [f, g=*f_begin](int x) { return g(f(x)); };
关于c++ - 组成Lambda函数 vector 时出现Segfault,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46901020/