C++STL容器毫无例外地是不可用的,我们能做些什么呢

C++ STL Containers are unusable without exceptions, what can we do about this?

本文关键字:我们 做些什么 毫无例外 C++STL      更新时间:2023-10-16

C++的理念是"用什么,付什么"。然而,由于异常及其在STL中的广泛使用,这可能会使人非常虚弱。

在有人说"打开异常"之前,我们必须生活在编程环境中,生活并不宽裕。我的是内核编程,执行环境没有提供足够的C++运行时来展开堆栈,等等。

当STL容器无法为其底层后备存储重新分配存储时,它们将抛出分配失败异常。当环境中没有启用异常时,程序会神秘地崩溃:我看到实现直接中止,或者只是假设分配有效,即使它没有。

我遇到的许多C ADT库通过返回错误代码或将错误作为输出参数来提前处理这个问题。

处理这个问题的"最佳"C++方法是什么?

澄清

我不想使用标准库,我不能。我不是在问"不能做的事我该怎么做"。我在问:"如果有一个干净的石板,应该如何构建容器库。"

这很简单:不要再相信你应该为所有东西使用标准库

标准库旨在成为功能的默认位置。然而,这并不意味着它适用于所有情况。例如内核编程。这是一个相当小众的环境,在这里你需要对大多数C++程序员不关心的事情进行直接和明确的控制。

发出失败信号的C++标准机制,特别是容器内部内存分配之类的失败信号,是抛出异常。绝大多数应用程序都不会去捕捉这个异常;万一他们失忆了,他们就会死。这对他们来说很好。在这种情况下,返回错误代码充其量是困难的(考虑重新分配std::vector<std::string>。如果内部std::string中的一个是导致OOM的原因,会发生什么?谁会得到错误代码?既然异常是由std::string的复制构造函数引发的,你怎么会发信号通知构造函数失败?)。只有真正需要关心的人才会关心它

您在一个受限的环境中工作,这个环境不是标准库设计用来处理的。所以…不要在那种环境下使用它。

我的建议是找到一份EASTL。它真的是为这类事情而设计的。我链接到的Github repo有一些错误修复等等,但基本上还是一样的。这不是一个坏代码。它们类似STL的容器提供了大部分接口,因此它们可以大部分作为替换。但它们提供了专门控制内存分配的特殊功能。而且他们不会扔(或者至少,你可以关掉扔)。

问题似乎真的出在你的环境上。堆叠展开并不十分复杂。我可以理解为什么你想对它施加一些限制-抛出10MB对象是合法的C++-但即使在内核模式下,你也应该能够支持通过非虚拟调用抛出std::bad_alloc

考虑到这一点,STL的设计是完全合理的。接口只需要最低限度的异常支持,并且可以根据环境定制实现。