【发布时间】:2020-01-28 14:01:57
【问题描述】:
我写拉函数来链接(读取->通过...->接收器)
template<typename T>
auto pull(T &&stream) {
return std::forward<T>(stream);
}
// return void/read
// read -> sink
// read -> through
template<typename R, typename S>
auto pull(R &&read, S &sink) {
return sink(std::forward<R>(read));
}
// return read
// read -> through -> ...
template<typename R, typename T, typename... Ts>
auto pull(R &&read, T &through, Ts &&... args) {
return pull(through(std::forward<R>(read)), std::forward<Ts>(args)...);
}
读取函数,像这样,提供一个向量:
template<typename T>
auto values(T &begin, T &end) {
return [&](bool abort, auto cb) {
if (end != begin) {
cb(false, *begin++);
} else {
cb(true, *begin);
}
};
}
通过函数,像这样:
template<typename T, typename M>
auto Map(M &&mapper) {
return [&](auto &&read) {
return [&](bool abort, auto cb) {
read(abort, [&](bool end, T val) {
if (end)
cb(true, val);
else
cb(false, mapper(val));
});
};
};
}
像这样的接收函数:
template<typename T, typename R>
auto log(R &&read) {
std::function<void(bool, T)> more = [&](bool done, T val) {
if (!done) {
cout << val << endl;
read(false, more);
}
};
read(false, more);
}
然后在main函数中:
int main() {
vector<int> vec;
for (int i = 1; i < 4; i++) {
vec.push_back(i);
}
auto begin = vec.begin();
auto end = vec.end();
auto vals = values(begin, end);
auto mapper = [&](int val) { return val * 2; };
auto timesTwo = Map<int>(mapper);
auto newVals1 = pull(vals, timesTwo, timesTwo);
auto newVals2 = pull(vals, timesTwo);
auto logInt = [&](auto read) { log<int>(read); };
//pull(newVals1, logInt); // Segmentation fault, how to correct `pull` function to make this run right
pull(newVals2, logInt); // ok
return 0;
}
pull(newVals2, logInt); 工作正常,
但是pull(newVals1, logInt);抛出Segmentation fault;
我想让pull(newVals1, logInt); 正常工作。
我想,可能是pull函数中的一些错误,但我不知道在哪里,谁能帮助我?
【问题讨论】:
-
Lambda 通过 return 或使用 std::function 通过引用捕获所有信息来逃避其范围通常是一个危险信号
-
肯定还有另一个问题我还没有解决,但一个问题是您在
values的 lambda 中取消引用else子句中的end迭代器。 -
SegFault 意味着你毁了你的记忆!我之前被骂过!但那是真正的问题。我希望这会有所帮助!