我有一个功能,减少,看起来像:
// 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>&
,然后可以将其传递回recurses。
不幸的是,它为一些大输入吹了堆栈。我想将其转换为迭代,例如
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
)。
如果让函数的其余部分改变哪个参考被认为是好的,我怎么能丢失递归呢?
答案 0 :(得分:4)
最简单的解决方案是使用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()
}
请注意.get()
调用之前的其他.getNextPtr()
,它首先访问基础引用。您必须在所有成员函数调用上执行此操作。
或者,您可以在内部使用指针:
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()
}