递归到迭代而不重新绑定引用

Recursion to iteration without rebinding a reference

本文关键字:绑定 引用 新绑定 迭代 递归      更新时间:2023-10-16

我有一个函数,它被削减,看起来像:

// bar is basically a linked list with extra stuff tagged on
void recurses(std::unique_ptr<bar> & P)
{
  bool ok = decide_if_this_P_is_acceptable(P);
  if (!ok)
  {
     recurses(P->getNextPtr());
     return;
  }
  // Now do lots more stuff involving the reference P and P.reset()
}

bar 类公开了一个名为 getNextPtr() 的方法,该方法返回一个std::unique_ptr<bar>&,然后可以将其传递回递归。

不幸的是,这吹毁了一些大输入的堆栈。我想将其转换为迭代,例如

void recurses(std::unique_ptr<bar> & P)
{
  bar * N = nullptr;
  for (;;)
  {
    bool ok = decide_if_this_P_is_acceptable(P);
    if (ok)
    {
       break;
    }
    P = P->getNextPtr();
  }
  // P is now OK
  // Now do lots more stuff involving the reference P and P.reset()
}

这当然拒绝编译,因为我们不能重新绑定引用(std::unique_ptr<bar> & P)。

我怎样才能丢失递归,同时让函数的其余部分改变任何被认为是好的引用?

最简单的解决方案是使用std::reference_wrapper而不是原始引用。它是可重新绑定的:

void recurses(std::reference_wrapper<std::unique_ptr<bar>>& P)
{
  bar * N = nullptr;
  for (;;)
  {
    bool ok = decide_if_this_P_is_acceptable(P);
    if (ok)
    {
       break;
    }
    P = P.get().getNextPtr();
  }
  // P is now OK
  // Now do lots more stuff involving the reference P and P.reset()
}

请注意.getNextPtr()调用之前的其他.get(),这些首先访问基础引用。您必须在所有成员函数调用中执行此操作。

或者,您可以在内部使用指针:

void recurses(std::unique_ptr<bar>& R)
{
  std::unique_ptr<bar>* P = &R;
  bar * N = nullptr;
  for (;;)
  {
    bool ok = decide_if_this_P_is_acceptable(*P);
    if (ok)
    {
       break;
    }
    P = &P->getNextPtr();
  }
  // P is now OK
  // Now do lots more stuff involving the reference P and P.reset()
}