monotonic_buffer_resource和异常处理

monotonic_buffer_resource and exception handling

提问人:Patrick Fromberg 提问时间:8/20/2023 最后编辑:HolyBlackCatPatrick Fromberg 更新时间:8/21/2023 访问量:70

问:

它的工作方式有点像一个只支持推送但不支持弹出的堆栈。 不幸的是,我看不出如何在捕获异常时恢复到以前的状态。monotonic_buffer_resource

即使在没有异常处理的情况下手动处理错误,也可能仍需要将数据回滚到以前的状态。如何捕获此分配器资源的状态,并在以后恢复到该状态?如果不可能,我可以使用其他资源吗?也许是非标准的?

否则,我是否错过了缺乏任何恢复到先前状态的方法的原因?在我看来,这应该非常简单,因为此分配资源无论如何都会跳过对析构函数的调用。monotonic_buffer_resource

C++ C++17 分配器

评论

1赞 Matt Timmermans 8/21/2023
它不会“跳过析构函数”。调用析构函数不是分配器的工作,但在资源销毁之前仍应调用析构函数。为此设计一种检查点/还原机制似乎非常困难,该机制在尊重 RAII 的程序中广泛有用,并且足够简单,可以在此资源中默认提供它。

答:

0赞 Nicol Bolas 8/21/2023 #1

虽然此分配器是“堆栈分配器”,但这并不意味着它生成的分配具有以任何方式受线程实际执行堆栈约束的生存期。也就是说,仅仅因为您将堆栈展开到某个点并不意味着在执行堆栈的现已终止部分内进行的所有分配现在都已失效。

您可以将这些分配用作某个对象的一部分,该对象现在驻留在展开后幸存下来的其他对象中。你不知道;您无法知道,因为分配器不会跟踪单个分配。事实上,不跟踪个人分配是重点

由于执行堆栈和分配堆栈是完全独立的,因此假设两者之间的关系非常危险的。如果你对如何使用单调分配很严格,那么你也许可以做一些你正在谈论的事情。但是,由于没有要求你这样做(而且非常非常容易出错),所以真的没有意义。

此外,它只是违反了类的设计意图。同样,重点是它跟踪个人分配。你分配了一堆东西,然后你同时把它们扔掉了。这就是使用模式。如果你的使用模式是分配一堆东西,扔掉其中的一些,然后分配更多,然后扔掉所有的东西,这就是不同的使用模式。

或者你只有两个。

评论

0赞 Patrick Fromberg 8/21/2023
我的用例如下。我有一个文本,我正在解析它。ast 元素进入分配器。但是当我回溯时,我必须回到某个点,在语法上尝试不同的路径。当我完成 ast 时,我会扔掉分配器资源,我不在乎任何破坏。目前,我正在为此目的使用 deque,它工作正常,但我不喜欢我有时使用单调资源,有时使用deque,因为我喜欢尽可能干燥。
0赞 Nicol Bolas 8/21/2023
目前尚不清楚在所描述的场景中使用堆栈分配器有什么问题。
0赞 Patrick Fromberg 8/21/2023
不知道“堆栈分配器”是什么意思。使用堆栈的分配器还是具有 push 和 pop 的分配器?单调资源分配器没有 POP,也不会在堆栈上分配。我的问题是回溯要求我在内存资源末尾丢弃任意数量的 ast 节点。在几乎所有情况下,我都可以忽略这个问题,只接受消耗百分之十的内存的惩罚。不幸的是,我不知道回溯的最大惩罚是什么,因为我不知道我的编译器会抛出什么语法。
1赞 Nicol Bolas 8/21/2023
@PatrickFromberg:“不知道你说的'堆栈分配器'是什么意思。 是“堆栈分配器”概念的实现。也就是说,它实现的行为就是成为“堆栈分配器”的含义。“我的问题是,回溯要求我在内存资源末尾丢弃任意数量的 ast 节点。”因此,唯一的问题是堆栈分配器保留的内存可能比严格需要的内存多。std::monotonic_buffer_resource
0赞 Patrick Fromberg 8/25/2023
@Bolas,没有。让我过于简单化了。我需要推和弹出。单调分配器没有爆裂声。我在评论中删除了术语“堆栈分配器”,因为似乎大多数人似乎将该术语与在堆栈上使用缓冲区的分配器相关联。它们并不意味着具有堆栈行为的分配器。单调分配器不是两种解释,因为它不使用堆栈,也没有实现 pop。看来我需要自己实现这个分配器(如果没有,我相信你会知道的)。我确实相信我的术语是正确的,但如果没有,我很乐意学习。