lambda 如何捕获自身以进行异步调用?

Par*_*ngh 3 c++ recursion lambda asynchronous

我必须在 lambda 内部进行异步调用,一旦异步调用终止,我必须调用 lambda 本身。

我尝试用代码解释我的问题:

typedef function<void(int id)> Callback;
Run Code Online (Sandbox Code Playgroud)
AsyncWork1(Callback call, int id, string)
{
    //...
    call(id);
}

AsyncWork2(Callback call, int id, double, string)
{
    //...
    call(id);
}
Run Code Online (Sandbox Code Playgroud)
void AsyncWorks(Callback final_callback, int id)
{
    Callback lambda = [&lambda, final_callback, id](int next_work) -> void
        {
            if(next_work == 1)
            {
                //...
                AsyncWork1(lambda, 2, "bla bla");
            }
            else if(next_work == 2)
            {
                //...
                //the lambda variable no longer exists
                AsyncWork2(lambda, 3, 0.0, "bla bla");
            }
            else if(next_work == 3)
            {
                //...
                final_callback(id);
            }
        };

    lambda(1);
}
Run Code Online (Sandbox Code Playgroud)
int main()
{
    AsyncWorks(...);

    AsyncWorks(...);

    AsyncWorks(...);

    AsyncWorks(...);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是,当代码从“AsyncWorks(...)”函数退出时,局部变量“lambda”不再存在。

我读过几个讨论 lambda 递归的线程,但我还没有找到任何解决方案。

我怎么解决这个问题?

Yak*_*ont 5

基本问题是 C++ 不会将thislambda 指针暴露给自身。

碰巧的是,有许多语言在定义某事物时无法引用其本身。这在函数式语言中使用一种称为“Y Combinator”的技术来解决。

C++ 中的简单 y 组合器如下所示:

template<class F>
struct y_combinator_t {
  F f;
  template<class...Args>
  auto operator()(Args&&...args)
  -> std::result_of_t< F&( y_combinator_t<F>&, Args&&... ) >
  {
    return f( *this, std::forward<Args>(args)... );
  }
};
template<class F>
y_combinator_t<std::decay_t<F>> y_combinate( F&& f ) {
  return {std::forward<F>(f)};
}
Run Code Online (Sandbox Code Playgroud)

我有两种想法,我们是否应该这样做,f( *this或者f( f,有时我会这样做。

使用:

void AsyncWorks(Callback final_callback, int id)
{
  Callback lambda = y_combinate(
    [final_callback, id]
    (auto& self, int next_work)
    -> void
    {
      if(next_work == 1) {
        //...
        AsyncWork1(self, 2, "bla bla");
      } else if(next_work == 2) {
        //...
        //the lambda variable no longer exists
        AsyncWork2(self, 3, 0.0, "bla bla");
      } else if(next_work == 3) {
        //...
        final_callback(id);
      }
    }
  );
  lambda(1);
}
Run Code Online (Sandbox Code Playgroud)

基本上,我self向 lambda 函数体添加了一个隐式参数。的调用者operator()看不到此参数。

Y 组合器基于我自己的这篇文章并进行了修改。

  • `y_combinate` -&gt; `y_combine`? (2认同)