std::error_code 的用例

Posted

技术标签:

【中文标题】std::error_code 的用例【英文标题】:Use cases for std::error_code 【发布时间】:2015-11-20 19:51:52 【问题描述】:

最近我一直在转换一些库以使用 C++11 中的 <system_error> 工具。

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

注意,我了解其中的区别 - 有 many questions on *** 可以解决区别。

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

好的 - 但我无法理解为什么我们会在实践中使用 std::error_code。在我看来,你要么去:

    处理系统特定的错误报告机制(如 比如,errno 或者从 POSIX 调用返回的东西,或者说,一个调用 在 Linux 上使用 SO_ERRORgetsockopt),您可以轻松地 通过std::errc 枚举转换为std::error_condition,它们应该是可移植的。

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

    处理一些定义了自己的错误报告机制的低级接口或库,例如 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

【问题讨论】:

this不清楚呢? @LightnessRacesinOrbit,这个想法很明确——但我看不到在实践中使用error_code。您提供的链接说:“每个std::error_code 对象都包含一对源自操作系统或某些低级接口的错误代码” - 好的,但是操作系统会给您一个 POSIX 错误(它是可移植的并且可以轻松转换为std::error_condition)或其他类型的低级错误(例如我猜是Win32错误),然后您需要手动映射到std::error_code - 但是有什么用将其映射到error_code? ... ...如果您需要做一些特定于平台的事情,您可以直接使用平台设施。如果您需要将错误转换为更通用的内容,请使用 error_condition。我只是不明白 error_code 是如何适应这些的。 该答案为您提供了一个“实践中”的用例。 “error_condition 是“可移植的抽象”,因此将是提供给用户的通用错误消息,而 error_code 将是对特定调试有用的平台相关信息。” 老实说,我不知道解决不了问题。 也许我只是很密集,但我就是不明白。 “error_code 将是对特定调试有用的平台相关信息” ???对我来说,使用error_code 在这里听起来是多余的。实际的平台相关信息本身对特定调试有用。如果您不处理抽象,为什么还要执行转换为 error_code 的额外步骤? 【参考方案1】:

不久前我自己也在想这个问题,并找到了答案here。本质上,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== 为该对@ 返回true 987654335@ 和error_code。这样您就可以从自己的错误类别中获得error_codes,并使它们等同于某些通用或系统error_conditions。

【讨论】:

我想澄清一下,库应该用error_codes 发出错误信号,并声明或重用标准error_condition 枚举来匹配它们。通过这种方式,有关错误的完整信息被传递,并且此类库的用户可以将其打印到日志中。但额外的细节对上层程序逻辑是隐藏的。 同意解释。这也表明 API 应该更倾向于将 error_code 作为无损实际错误值传播,其中操作的代码测试结果应该导致隐式转换为 error_condition,其中可能定义其他类别以折叠和转换系统-与平台无关的故障场景的特定错误值。 我想说我一直在研究这个相同的主题,但我完全不知道如何应用它。即使在 C++17 中,在打开流以匹配为同一错误定义的 error_condition 时,获得像“找不到文件”(ENOENT) 的错误代码这样简单的内容似乎也无法按预期工作。

以上是关于std::error_code 的用例的主要内容,如果未能解决你的问题,请参考以下文章

属性与描述符与 __getattribute__ 的用例

UML设计,可以设计程序的用例图类图活动图等_SurfaceView

python使用discover方法遍历所有要执行的用例

pytest文档40-pytest.ini配置用例查找规则(面试题)

一 基础使用

pytest接口自动化测试框架 | 使用装饰器修饰需要运行的用例