std::function . .
. Undefined , .
, Euclid gcd() . , :
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a%b);
}
, . this this ( , -, ). , ?
std::function
std::function:
std::function<int(int, int)> gcd = [&](int a, int b){
return b == 0 ? a : gcd(b, a%b);
};
, . ( ), ( gcd gcd , ), .
:
auto gcd_self = std::make_shared<std::unique_ptr< std::function<int(int, int)> >>();
*gcd_self = std::make_unique<std::function<int(int, int)>>(
[gcd_self](int a, int b){
return b == 0 ? a : (**gcd_self)(b, a%b);
};
};
( ), /, . , .
Y-combinator
:
template <class F>
struct y_combinator {
F f;
template <class... Args>
decltype(auto) operator()(Args&&... args) const {
return f(*this, std::forward<Args>(args)...);
}
};
template <class F>
y_combinator<std::decay_t<F>> make_y_combinator(F&& f) {
return {std::forward<F>(f)};
}
gcd :
auto gcd = make_y_combinator(
[](auto&& gcd, int a, int b){
return b == 0 ? a : gcd(b, a%b);
}
);
y_combinator -, , , . , .
, "recurse" . , .
y_combinator , , "recurse" ( , y_combinator) . , y_combinator, .
:
auto foo = make_y_combinator( [&](auto&& recurse, some arguments) {
// write body that processes some arguments
// when you want to recurse, call recurse(some other arguments)
});
.
( ) @Barry .