好吧,您的代码不起作用。但这确实是:
template<class F>
struct ycombinator {
  F f;
  template<class...Args>
  auto operator()(Args&&...args){
    return f(f, std::forward<Args>(args)...);
  }
};
template<class F>
ycombinator(F) -> ycombinator<F>;
测试代码:
ycombinator bob = {[x=0](auto&& self)mutable{
  std::cout << ++x << "\n";
  ycombinator ret = {self};
  return ret;
}};
bob()()(); // prints 1 2 3
您的代码既是UB代码,又是格式错误的代码,无需诊断。哪个好笑;但两者都可以独立固定。
首先,UB:
auto it = [&](auto self) { // outer
  return [&](auto b) { // inner
    std::cout << (a + b) << std::endl;
    return self(self);
  };
};
it(it)(4)(5)(6);
这是UB,因为外部self按值取值,然后内部self按引用捕获,然后在outer完成运行后继续将其返回。因此,segfaulting绝对可以。
解决方法:
[&](auto self) {
  return [self,&a](auto b) {
    std::cout << (a + b) << std::endl;
    return self(self);
  };
};
代码保留格式不正确。要看到这一点,我们可以扩展lambda:
struct __outer_lambda__ {
  template<class T>
  auto operator()(T self) const {
    struct __inner_lambda__ {
      template<class B>
      auto operator()(B b) const {
        std::cout << (a + b) << std::endl;
        return self(self);
      }
      int& a;
      T self;
    };
    return __inner_lambda__{a, self};
  }
  int& a;
};
__outer_lambda__ it{a};
it(it);
实例化__outer_lambda__::operator()<__outer_lambda__>:
  template<>
  auto __outer_lambda__::operator()(__outer_lambda__ self) const {
    struct __inner_lambda__ {
      template<class B>
      auto operator()(B b) const {
        std::cout << (a + b) << std::endl;
        return self(self);
      }
      int& a;
      __outer_lambda__ self;
    };
    return __inner_lambda__{a, self};
  }
  int& a;
};
所以我们接下来必须确定的返回类型 __outer_lambda__::operator()。
我们逐行进行。首先我们创建__inner_lambda__类型:
    struct __inner_lambda__ {
      template<class B>
      auto operator()(B b) const {
        std::cout << (a + b) << std::endl;
        return self(self);
      }
      int& a;
      __outer_lambda__ self;
    };
现在,看那里-它的返回类型为self(self),或__outer_lambda__(__outer_lambda__ const&)。但是我们正在尝试推导的返回类型__outer_lambda__::operator()(__outer_lambda__)。
您不允许这样做。
实际上,的返回类型__outer_lambda__::operator()(__outer_lambda__)实际上并不取决于的返回类型__inner_lambda__::operator()(int),但是C ++在推断返回类型时并不在意;它只是逐行检查代码。
和 self(self)在我们推论之前使用。病态的程序。
我们可以隐藏它,self(self)直到以后再打补丁:
template<class A, class B>
struct second_type_helper { using result=B; };
template<class A, class B>
using second_type = typename second_type_helper<A,B>::result;
int main(int argc, char* argv[]) {
  int a = 5;
  auto it = [&](auto self) {
      return [self,&a](auto b) {
        std::cout << (a + b) << std::endl;
        return self(second_type<decltype(b), decltype(self)&>(self) );
      };
  };
  it(it)(4)(6)(42)(77)(999);
}
现在代码正确并可以编译了。但是我认为这有点骇人听闻。只需使用ycombinator。