【问题标题】:How can C++ use continuation-passing style?C++ 如何使用延续传递风格?
【发布时间】:2011-12-16 22:12:44
【问题描述】:

假设在 C++ 中,您对递归函数执行了太多递归调用,并出现堆栈溢出错误。

您将如何以连续传递样式重写此代码以避免堆栈溢出?

我在用 C++ 描述这个有点困难。

【问题讨论】:

  • 对于这样一个抽象的问题,除了抽象的答案之外,你什么也得不到。也许您应该发布导致堆栈溢出的示例函数,然后您将获得有关如何修复它的具体答案。 (就个人而言,我会尝试重写函数以使用累加器,然后再重写它以使用延续......)
  • @ildjarn,感谢您的通知。我实际上正在寻找一个抽象的答案。如果我使用累加器,我最终不会将其重写为 C++ 中的正常迭代吗?
  • @highwind7777 :您希望得到什么样的抽象答案? “使用有状态函子”?这似乎太高级了,无济于事,但是如果没有更详细的问题,很难想出更具体的东西...关于使用累加器,不,只要您的编译器支持 TCO,您就可以坚持使用递归。

标签: c++ recursion stack-overflow continuations


【解决方案1】:

这是一个相当开放的问题,但 Eric Lippert 写了一个(实际上是两个)而不是 long series about exactly this topic。不完全正确的语言,但它应该还是很有帮助的,并且给出了一般的想法。

虽然在 C++ 中实现 CPS 似乎只是为了修复单个递归函数需要做很多工作,但当您可以使用某种算法使函数与队列迭代时(您仍然使用基本相同数量的数据,但是堆的限制要少得多)。

【讨论】:

  • 在将词法闭包作为内置语言功能的语言的上下文中编写这两个系列时,我有一个明显的好处。将 C++ 代码重写为闭包当然是完全可以实现的,但是会有点痛苦。
  • @EricLippert 你说得对,我假设 c++11 lambdas,但显然不是每个人(甚至不是大多数人)都有支持 lambdas 的编译器。没有它,它会变得更加复杂(使用类并大概传递那些?)。顺便说一句,感谢您的精彩文章 - 没有您,我什至不知道 CPS 是什么 :)
  • @Voo :即使没有 C++11 lambda,也有 C++03 库可以轻松处理这个问题。参见例如Boost.Phoenix.
  • 感谢您的链接。 @EricLippert 通过将 C++ 代码重写为闭包,您的意思是通过将它们传递到调用链中来手动保持关闭(有界)变量的活动吗?
  • @highwind7777 如果你想实现闭包,函数指针并不是很有帮助。不知道 boost 是如何做到的,但是您需要在某个地方进行存储,而不仅仅是指向可执行代码的指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 2011-06-30
  • 2010-12-21
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
相关资源
最近更新 更多