std::error_code 的用例

Use cases for std::error_code

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

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

请注意,我理解其中的区别 - 有 many questions on Whosebug 说明了其中的区别。

基本区别在于 std::error_code 应该代表系统或平台特定的错误,而 std::error_condition 是 API 或用户界面应该 return.

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

  1. 正在处理系统特定的错误报告机制(例如 例如,errno 或 return 从 POSIX 电话中编辑的东西,或者说,电话 getsockopt 和 Linux 上的 SO_ERROR),你可以很容易地 通过 std::errc 枚举转换为 std::error_condition,这应该是可移植的。

  2. 使用用户定义的错误类别,代表应用程序级别 或业务逻辑错误,例如 "invalid social security number" 或 不管怎样——这也是一个用例 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 的一些示例用例是什么?

我自己也在想这个问题并找到了答案 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 恰好包含它所源自的子系统的类别。这对于调试和报告错误很有用:您可能有兴趣知道 "permission denied" 错误是因为本地文件系统上的访问权限不足还是因为您的 http-downloader-library 收到 403 错误, 并且可能想在错误消息中添加该详细信息,但您的程序必须以任何一种方式中止。

什么构成等价由类别定义;如果 error_code 的类别认为 error_condition 等价, error_condition 的类别认为 error_code 等价,则 operator== returns true 对于那对 error_conditionerror_code。这样你就可以从你自己的错误类别中得到 error_codes 并使它们等同于某些通用或系统 error_conditions.