std::error_code的使用案例

34

最近我一直在将一些库转换为使用C++11中的<system_error>设施。

我很难理解std::error_codestd::error_condition的使用案例。

注意,我理解它们之间的区别 - 在stackoverflow上有很多问题讨论了这个问题。

基本的区别是std::error_code应该表示系统或平台特定的错误,而std::error_condition是API或用户界面应该返回的抽象错误。

好吧 - 但我很难理解为什么我们会在实践中使用std::error_code。在我看来,你要么:

  1. 处理系统特定的错误报告机制(例如,errno或从POSIX调用返回的内容,或在Linux上使用带有SO_ERRORgetsockopt调用),您可以通过std::errc枚举轻松转换为std::error_condition,这应该是可移植的。

  2. 使用用户定义的错误类别,表示应用程序级别或业务逻辑错误,例如“无效社会安全号码”或其他情况-这也将是std::error_condition的一个用例。

  3. 处理一些低级接口或库,该接口或库定义了自己的错误报告机制,例如OpenSSL,在这种情况下,您将直接使用平台特定的错误机制。在这种情况下,您需要将这些错误转换或映射为std::error_code。但是,如果您要将这些平台特定错误转换为通用类型,例如std::error_code,为什么不直接转换为std::error_condition呢?

此外,由于POSIX系统错误应该是可移植的,并且它们通过std::errc枚举与std::error_condition一一映射,因此我找不到任何使用std::error_code的用例。大多数Linux / UNIX系统调用设置errno,这应该可以可移植地映射到std::error_condition。因此,我在任何地方都看不到使用std::error_code的用例。那么,有哪些示例用例,我们希望使用std::error_code而不是std::error_condition呢?

1
@LightnessRacesinOrbit,这个想法很清晰 - 但我不看到在实践中使用error_code的用处。您提供的链接说:“每个std::error_code对象都包含一个来自操作系统或某些低级接口的错误代码对”-好吧,但是操作系统将给您提供一个POSIX错误(它是可移植的,可以轻松地转换为std::error_condition)或其他类型的低级错误(例如我猜测是Win32错误),然后您需要手动将其映射到std :: error_code - 但是将其映射到error_code有什么用?... - Siler
如果你需要做一些特定于平台的事情,你直接使用平台设施。如果你需要将错误转换为更通用的形式,你可以使用error_condition。我只是不明白error_code如何适用于这些情况。 - Siler
那个回答为你提供了一个“实际应用”的用例。 “error_condition”是“可移植抽象”,因此应该是要给用户的通用错误消息,而“error_code”则是平台相关信息,对于特定的调试非常有用。老实说,我不明白问题出在哪里。 - Lightness Races in Orbit
但是对于实际的接口(比如API),我们不是应该使用std::error_condition来处理吗? - Siler
1
error_code --> 出现了一个错误, error_condition --> 我们能做些什么来解决它 - user10133158
显示剩余4条评论
1个回答

32

我之前也曾经对此产生了疑问,后来在这里找到了答案。简而言之,error_code 用于存储和传输错误代码,而 error_condition 用于匹配错误代码。

void handle_error(error_code code) {
   if     (code == error_condition1) do_something();
   else if(code == error_condition2) do_something_else();
   else                              do_yet_another_thing();
}

每个 error_condition 相当于一组 error_code,可能来自不同的 error_categories。这样,您可以将某种类型的所有错误视为相同,而不管它们来自哪个子系统。

另一方面,error_code 正好包含它所起源的子系统的类别。这对于调试和报告错误非常有用:您可能想知道“权限拒绝”错误是因为本地文件系统上访问权限不足,还是由您的 http-downloader-library 收到了 403 错误,您可能想将那些详细信息放入错误消息中,但无论如何,您的程序都必须中止。

等价物的构成由类别定义;如果 error_code 的类别认为 error_condition 等效或 error_condition 的类别认为 error_code 等效,则 operator== 会为该对 error_conditionerror_code 返回 true。这样,您可以拥有来自自己的错误类别的 error_code 并使它们等效于特定的通用或系统 error_condition


4
我会尽力做到最好。以下是需要翻译的内容:我想要澄清的是,一个库应该使用 error_code 来表示错误,并声明或重复使用标准的 error_condition 枚举来匹配它们。这样,关于错误的全部信息都会被传递,这个库的用户可以将其打印到日志中等等。但是,额外的细节对于上层程序逻辑来说是隐藏的。 - Constantin Baranov
同意解释。这也表明API应该更喜欢传播“error_code”作为不会丢失的实际错误值,其中代码测试操作的结果应该导致隐式转换为“error_condition”,在这种情况下可能定义了其他类别以折叠和转换系统特定的错误值到平台无关的失败场景。 - charley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接