使用std::error_code处理非整数值

5
我正在编写一个库,在远程系统返回错误时想要返回错误代码。问题是这些错误由字符串标识,例如"0A01",并且包含消息,但错误代码需要整数作为值。
最佳方法是如何实现错误代码,并具有std::error_code提供的所有功能,但使用字符串作为值?我如何将外部错误字符串添加到std::error_codestd::error_category中?

1
异常? - Quentin
我想使用error_codes。这更符合应用程序的流程。 - ruipacheco
如果这些字符串代码的数量是固定的,那么您可以将它们映射到整数值(特别是因为它们看起来像十六进制值),然后仍然可以使用std::error_code。否则,编写一个具有两个字符串字段的类应该不难。 - freakish
固定数量的代码。我想我可以子类化 error_code 并添加另一个属性。 - ruipacheco
它们是 ASCII 码,长度小于 8 个字符。是的。 - ruipacheco
显示剩余4条评论
1个回答

3
如评论中所述,您必须了解可能从远程服务器接收到的错误代码。从远程服务器接收到的std::string包含两部分,正如您所说,

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

由于您没有分享错误消息的格式,因此我不会添加拆分它的代码,请将您的字符串拆分为2个部分,
  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.

您可以使用此帖子中的string_to_hexadecimal()函数来进行转换。

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

编辑1:

正如您所说:

这假设动态消息是全局值。我如何将其传递给std::error_category对象?

您可以看到,std::error_code::assign和构造函数std::error_code::error_code都采用int类型的参数作为错误代码编号和error_category。因此,显然std::error_code无法获取动态消息。

但是,请等一下,我说过std::error_code在构造函数中使用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
1
@ruipacheco:如果您只在从网络获取到错误信息时才知道它们,您可以将消息存储在 OurCustomErrCategory 的成员中并添加方法来存储它们。这假设从错误代码到消息的映射是恒定的,即如果两个错误代码相同,则消息也相同。 - PaulR
@ruipacheco,代码有什么问题吗?我能为您提供什么帮助吗? - Sahib Yar
@SahibYar 我们需要一个指向std::error_category子类的静态引用,这意味着我不能重载make_error_code()。你写的代码会崩溃。请查看https://ned14.github.io/outcome/tutorial/error_code/ - ruipacheco
@SahibYar 给了你答案,我误解了我的问题。 - ruipacheco

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