如何编写一个错误结构,该结构可以包含不同的强键枚举作为错误代码

How to write an error struct which can contain different strongly typed enums as the error code?

本文关键字:结构 包含不 错误代码 枚举 何编写 一个 错误      更新时间:2023-10-16

我想编写一个简单的错误struct,其中包含某种错误代码和std::string作为消息。错误代码可能是一个简单的INT,也可以是任何强烈键入的枚举,例如:

enum class NetworkErrorCode {
OK = 0,
CONNECTION_FAILURE,
EMPTY_RESPONSE,
HOST_RESOLUTION_FAILURE,
UNKNOWN_ERROR = 1000,
};

我可以编写一个结构,该结构对每个不同的枚举具有不同的过载构造函数,它可能包含将它们转换为int以存储它们。但是在这种情况下,我会失去将错误代码与以后的实际枚举值进行比较的可能性。我还需要为每种可能的类型编写一个比较操作员。

我也可以使用这样的模板:

template<typename T>
struct Error
{
  T const code;
  std::string const message;
};

但是现在我将无法创建这样的错误:

Error{NetworkErrorCode::CONNECTION_FAILURE, "some message"}

我需要写:

Error<NetworkErrorCode>{NetworkErrorCode::CONNECTION_FAILURE, "some message"}

是否有一种方法可以避免像第一个解决方案一样避免编写大量锅炉板代码,同时仍然可以在不明确指定类型的情况下创建它们的可能性?我听说过C 17中类模板构造函数的模板参数扣除,但我无法绕过它。

using error_code = std::variant<int, NetworkErrorCode, AnotherErrorCode /*etc*/>;
struct Error {
  error_code code;
  std::string message;
};

这要求您在一个位置列出所有错误代码类型;但这比编写要写的构造函数要少。

Error{NetworkErrorCode::CONNECTION_FAILURE, "some message"}

在不编写其他构造函数的情况下工作,因为变体将从其任何可能的类型中转换。

要获得访问权限,您拥有std::visit.get<Type>()之类的。error_code上的==通常应该只能使用(有时您可能必须将另一个参数明确地施加给error_code(。

您需要做的就是添加一个ctor,如以下

Error(T const t, const string s)  : code(t), message(s) {}

然后使用C 17符合编译器,您将全部设置。

您可以在Godbolt上检查它,https://godbolt.org/g/dyznp8

请注意,这使用C 17模板参数对类模板构造函数扣除而不是使用变体。

此处列出了完整的示例代码,以供您参考,

#include <string>
using namespace std;
enum class NetworkErrorCode {
    OK = 0,
    CONNECTION_FAILURE,
    EMPTY_RESPONSE,
    HOST_RESOLUTION_FAILURE,
    UNKNOWN_ERROR = 1000
};
template<typename T>
struct Error
{
  T const code;
  std::string const message;
  Error(T const t, const string s)  : code(t), message(s) {}
};
template <typename T>
auto getStuff() -> variant<string, Error<T>> {
    variant<string, Error<T>> w;
    return w;
}
int main() {
    int i = 2;
    if (i == 1) {
        Error{NetworkErrorCode::CONNECTION_FAILURE, "some message"};
    }
}

您可以用-std=c++17进行编译。