【发布时间】:2018-04-07 10:58:43
【问题描述】:
我有以下代码试图以 CPS 形式定义程序。
#include <iostream>
#include <utility>
#include <type_traits>
#include <string>
using namespace std;
template <typename T> using Func = std::function<T>;
template <typename T> using Cont = Func<void (T &&)>;
template <typename T, typename U> using Proc = Func<void (T &&, Cont<U>)>;
template <typename T> struct RevProc;
template <typename T, typename U> struct RevProc<Proc<T, U>> {
using ArgType = T;
using RetType = U;
};
template <typename P1, typename P2> auto pipe(P1 proc1, P2 proc2)
-> Proc<typename RevProc<P1>::ArgType, typename RevProc<P2>::RetType> {
using T = typename RevProc<P1>::ArgType;
using U = typename RevProc<P2>::ArgType;
static_assert(is_same<U, typename RevProc<P1>::RetType>::value,
"Mismatch procedure type.");
using V = typename RevProc<P2>::RetType;
return [&] (T &&t, Cont<V> pass) {
proc1(move(t), [&] (U &&u) {
proc2(move(u), pass);
});
};
}
template <typename P1, typename P2, typename... Ps> auto pipe(P1 proc1, P2 proc2, Ps ...procs)
-> Proc<typename RevProc<P1>::ArgType, typename RevProc<decltype(pipe(proc2, procs...))>::RetType> {
auto proc2s = pipe(proc2, procs...);
return pipe(proc1, proc2s);
}
int main() {
Func<void ()> var1;
Cont<int> var2([] (int &&x) {});
Proc<int, int> var3([] (int &&x, Cont<int> pass) {
pass(x + 1);
});
auto var4 = pipe(var3, var3);
var4(42, [] (int &&x) {
cout << x << endl;
});
Proc<string, int> var5([] (string &&str, Cont<int> pass) {
pass(str.length());
});
// auto var6 = pipe(var5, var5);
Proc<int, int> var7 = pipe(var3, var3, var3);
// var7(42, [] (int &&x) {
// cout << x << endl;
// });
auto var8 = pipe(var5, var3, var3);
var8("something", [] (int &&x) {
cout << x << endl;
});
return 0;
}
如果我取消注释 var6 行,编译器会按预期抛出错误。但是,如果 var7 或 var8 的调用未注释,则代码通过编译但会在运行时触发随机分段错误或总线错误。代码在构建 lambda 时是安全的,但在应用时会崩溃。
感谢您指出我的错误。
如果我将代码修改为,补充它运行良好可能会很有用
var7 = pipe(var3, pipe(var3, var3));
如var8。
我随机尝试并修复了,令我惊讶的是。我只保留第一个声明并通过复制第一个来修改第二个:
template <typename P1, typename P2, typename... Ps> constexpr auto pipe(P1 proc1, P2 proc2, Ps ...procs)
-> Proc<typename RevProc<P1>::ArgType, typename RevProc<decltype(pipe(proc2, procs...))>::RetType> {
using T = typename RevProc<P1>::ArgType;
using U = typename RevProc<P2>::ArgType;
static_assert(is_same<U, typename RevProc<P1>::RetType>::value,
"Mismatch procedure type.");
using V = typename RevProc<P2>::RetType;
return [&] (T &&t, Cont<V> pass) {
proc1(move(t), [&] (U &&u) {
pipe(proc2, procs...)(move(u), pass);
});
};
}
那么,到底是什么?
【问题讨论】:
-
声明
auto proc2s却不使用是什么原因? -
对不起,那只是调试人员。已编辑。
标签: c++ c++11 lambda functional-programming segmentation-fault