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_code
与 std::error_condition
的用例。
注意,我了解其中的区别 - 有 many questions on *** 可以解决区别。
基本区别在于std::error_code
应该表示系统或平台特定的错误,而std::error_condition
是 API 或用户界面应返回的抽象错误。
好的 - 但我无法理解为什么我们会在实践中使用 std::error_code
。在我看来,你要么去:
处理系统特定的错误报告机制(如
比如,errno
或者从 POSIX 调用返回的东西,或者说,一个调用
在 Linux 上使用 SO_ERROR
到 getsockopt
),您可以轻松地
通过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_code
s,并使它们等同于某些通用或系统error_condition
s。
【讨论】:
我想澄清一下,库应该用error_code
s 发出错误信号,并声明或重用标准error_condition
枚举来匹配它们。通过这种方式,有关错误的完整信息被传递,并且此类库的用户可以将其打印到日志中。但额外的细节对上层程序逻辑是隐藏的。
同意解释。这也表明 API 应该更倾向于将 error_code
作为无损实际错误值传播,其中操作的代码测试结果应该导致隐式转换为 error_condition
,其中可能定义其他类别以折叠和转换系统-与平台无关的故障场景的特定错误值。
我想说我一直在研究这个相同的主题,但我完全不知道如何应用它。即使在 C++17 中,在打开流以匹配为同一错误定义的 error_condition 时,获得像“找不到文件”(ENOENT) 的错误代码这样简单的内容似乎也无法按预期工作。以上是关于std::error_code 的用例的主要内容,如果未能解决你的问题,请参考以下文章
UML设计,可以设计程序的用例图类图活动图等_SurfaceView