Ваша рекурсивная лямбда сталкивается с проблемой;для этого требуется точная переменная, в которой он был создан, или UB, чтобы вызвать его.
auto ycomb = [](auto&&f){ return [f=f](auto&&...args){ return f(f, decltype(args)(args)...); }; };
эта маленькая игрушка исправляет эту ошибку.
auto power = ycomb( [](auto&& self, int a, unsigned int n)->int
{
return (n==0) ? 1 : a*self(self, a, n-1);
});
там.
ycomb
- это ycombinator.Он знаменит.
Этот power
можно скопировать и безопасно пережить сферу его строительства.
Если вам не нравится self(self, args...)
, вы можете использовать ycombinator, чтобы сделать его:
auto ycomb0 = [](auto&&f){
return [=](auto&&...args){
return f(f, decltype(args)(args)...);
};
};
auto ycombx_ref = [](auto&& r, auto&& f) {
return [&r, f](auto&&...args) {
return f( r(r, f), decltype(args)(args)... );
};
};
auto ycomb = ycomb0( ycombx_ref );
и теперь self
, переданный лямбде, сам по себе не нуждается в передаче самостоятельно:
auto power = ycomb( [](auto&& self, int a, unsigned int n)->int
{
return (n==0) ? 1 : a*self(a, n-1);
});
Пример в реальном времени .