type の関数を操作する次のコードを作成しましたfunction<int(int)>
。関数compose
、print
、inc
およびguarded
は、他の関数を組み合わせたり、何らかの外部効果を生成したりするヘルパーです。次に、それらを使用してプログラムを構築します。
/* start of the program */
function<int(int)> recursion();
function<int(int)> go =
compose(guarded(10, recursion()), compose(inc, print("go")));
function<int(int)> recursion() {
return compose(go, print("recursion"));
}
ただし、 を呼び出すと、 に 2 回目に達したときにrecursion()(0)
例外std::bad_function_call
がスローされましたgo
が、その理由はわかりません。ダングリング参照または空はありますstd::function
か? さらに、エータ展開は次のようにgo
機能します。
function<int(int)> go = [](int n) -> int {
return compose(guarded(10, recursion()), compose(inc, print("go")))(n);
};
元のコードの何が問題になっていますか? 代替手段が機能するのはなぜですか?
完全なコード:
#include <string>
#include <iostream>
#include <functional>
using namespace std;
/* helper functions, some combinators */
//composing two functions, f1 . f2
function<int(int)> compose(const function<int(int)>& f1, const function<int(int)>& f2) {
return [f1,f2](int n) -> int {
return f1(f2(n));
};
}
function<int(int)> print(const string& msg) {
return [msg](int n) -> int {
cout << "print: " << msg << endl;
return n;
};
}
function<int(int)> inc = [](int n) -> int {
cout << "in inc lambda: " << n << endl;
return n+1;
};
//calls the given function `f` only when `n` is less then `m`
function<int(int)> guarded(int m, function<int(int)> f) {
auto g = [m,f](int n) -> int { return n<m? f(n) : m; };
return compose(g, print("guarded"));
}
/* start of the program */
function<int(int)> recursion();
function<int(int)> go =
compose(guarded(10, recursion()), compose(inc, print("go")));
function<int(int)> recursion() {
return compose(go, print("recursion"));
}
int main() {
try {
recursion()(0);
} catch (bad_function_call e) {
cout << "bad_function_call: " << e.what() << endl;
}
return 0;
}