【问题标题】:Using std::error_code with non-integer values将 std::error_code 与非整数值一起使用
【发布时间】:2017-10-06 23:38:49
【问题描述】:

我正在编写一个库,并且希望在远程系统返回错误时返回错误代码。问题是这些是由字符串标识的,例如“0A01”并且还包含一条消息,并且错误代码需要一个整数作为值。

使用std::error_code 提供的所有功能但使用字符串作为值的最佳方法是什么?如何将外部错误字符串添加到std::error_codestd::error_category

【问题讨论】:

  • 例外? ---
  • 我想使用 error_codes。更适合应用的流程。
  • 如果这些字符串代码的数量是固定的,那么您可以将它们映射为整数值(尤其是因为它们看起来像十六进制值)并使用std::error_code。否则编写一个包含两个字符串字段的类应该一点都不难。
  • 固定数量的代码。我想我可以继承 error_code 并添加另一个属性。
  • 这些字符串是否仅由十六进制数字组成?并且简短(不超过 8 个字符)?

标签: c++ c++11 error-code


【解决方案1】:

正如在 cmets 中提到的,您必须知道可以从远程服务器接收到的错误代码。 正如您所说,您从远程服务器收到的std::string 包含两部分,

问题是这些是由字符串标识的,例如“0A01”并且还包含一条消息,并且错误代码需要一个整数作为值。

由于您没有分享错误消息的格式,我没有添加用于吐出它的代码,将您的字符串分成两部分,

  1. 错误代码
  2. 错误消息

现在您可以使用std::stoi(error_code)std::string 类型的错误代码转换为int,所以可以说

int error_code_int = std::stoi(string_to_hexadecimal(error_code));

对于用作我们自定义错误消息的基类的std::error_category,请执行此操作,

std::string message_received = "This is the message which received from remote server.";

struct OurCustomErrCategory : std::error_category
{
  const char* name() const noexcept override;
  std::string message(int ev) const override;
};

const char* OurCustomErrCategory::name() const noexcept
{
  return "Error Category Name";
}

std::string OurCustomErrCategory::message(int error_code_int) const
{
    switch (error_code_int)
    {
    case 1:
        return message_received;

    default:
        return "(unrecognized error)";
  }
}

const OurCustomErrCategory ourCustomErrCategoryObject;

std::error_code make_error_code(int e)
{
  return {e, ourCustomErrCategoryObject};
}

int main()
{
    int error_code_int = std::stoi(string_to_hexadecimal(error_code));  // error_code = 0A01
    ourCustomErrCategoryObject.message(error_code_int);
    std::error_code ec(error_code_int , ourCustomErrCategoryObject);
    assert(ec);

    std::cout << ec << std::endl;
    std::cout << ec.message() << std::endl;
}

上述工作示例的输出是

Error Category Name : 0A01
This is the message which received from remote server.

您可以从this post 使用函数string_to_hexadecimal()

希望现在大家可以根据自己的需要修改上面的代码。

编辑 1:

如你所说:

这假定动态消息是一个全局值。我如何通过它 到std::error_category 对象?

您可以看到std::error_code::assign 和构造函数std::error_code::error_code 都使用int 的参数作为错误代码号和error_category。所以很明显std::error_code不能接受动态消息。

但是等等,我说std::error_codeerror_category 作为构造函数中的参数,那么有什么办法,我们可以在那里分配动态消息吗?

std::error_category 声明

std::error_category 用作特定错误的基类 类别类型。

所以这意味着我们在下面一行从std::error_category派生了struct

struct OurCustomErrCategory : std::error_category

可以有一个数据成员,我们可以通过成员函数来赋值,所以我们的struct会变成这样,

struct OurCustomErrCategory : std::error_category
{
    std::string message_received;
    OurCustomErrCategory(std::string m) : message_received(m) {}

    const char* name() const noexcept override;
    std::string message(int ev) const override;
};

你可以随意分配它,

const OurCustomErrCategory ourCustomErrCategoryObject("This is the message which received from remote server.");

【讨论】:

  • 这假定动态消息是一个全局值。如何将它传递给 std::error_category 对象?
  • @ruipacheco:您可以将消息存储在OurCustomErrCategory 的成员中,并添加方法以供您存储它们,前提是您仅在它们从网络到达时才知道它们。这假设从错误代码到消息的映射是恒定的,即如果两个错误代码相同,则消息将相同。
  • @ruipacheco 代码有什么问题,有什么可以帮助你的吗?
  • @SahibYar 我们需要对 std::error_category 子级的静态引用,这意味着我不能重载 make_error_code()。你写的代码崩溃了。检查ned14.github.io/outcome/tutorial/error_code
  • @SahibYar 给你答案,我误解了我的问题。
猜你喜欢
  • 1970-01-01
  • 2015-06-21
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-20
  • 2017-08-13
  • 1970-01-01
相关资源
最近更新 更多