概述
std::error_code主要包括两方面: error id和category, 要实现自己定义的error_code, 也就需要定义自己的error id和category.
如果只使用error id(例如Linux的errno)的话, 不同服务分开开发可能相同的errno代表的含义不同, 因此需要使用error id代表状态, 和category表示该error_code所在的域.
定义自己的error id: error num enum
- 定义自己的enum class:
enum class FlightsErrc {
NonexistentLocations = 10,
DatesInThePast,
InvertedDates,
NoFlightsFound = 20,
ProtocolViolation = 30,
ConnectionError,
ResourceError,
Timeout
};
- 特例化std::is_error_code_enum:
namespace std {
template <>
struct is_error_code_enum<FlightsErrc> : true_type {};
}
- 声明并实现std::error_code make_error_code(Your_Error_Enum):
在头文件中声明:
// .h文件
std::error_code make_error_code(FlightsErrc);
// .cpp文件
std::error_code make_error_code(FlightsErrc errc) {
// theFlightErrCategory是自己的category的一个实例, 见下面
return {static_cast<int>(errc), theFlightErrCategory};
}
定义自己的error_category
注意声明和实现自己的error_category在cpp源文件的一个编译单元即可, 其它使用的地方只需要该结构的一个实例地址.
需要继承std::error_category, 并实现name()和message()这两个纯虚函数.
struct FlightsErrCategory : std::error_category {
const char *name() const noexcept override;
std::string message(int ev) const override;
};
const char *FlightsErrCategory::name() const noexcept {
return "flights";
}
std::string FlightsErrCategory::message(int ev) const {
// enum class需要static_cast
switch (static_cast<FlightsErrc>(ev))
{
case FlightsErrc::NonexistentLocations:
return "nonexistent airport name in request";
break;
case FlightsErrc::DatesInThePast:
return "request for a date from the past";
break;
case FlightsErrc::InvertedDates:
return "requested flight return date before departure date";
break;
case FlightsErrc::NoFlightsFound:
return "no filight combination found";
break;
case FlightsErrc::ProtocolViolation:
return "received malformed request";
break;
case FlightsErrc::ConnectionError:
return "could not connect to server";
break;
case FlightsErrc::ResourceError:
return "insufficient resources";
break;
case FlightsErrc::Timeout:
return "processing timed out";
break;
// 这里需要default用于传入非enum class范围的值
default:
return "(unrecognized error)";
}
}
// 注意定义一个category的示例用于实现make_error_code方法
const FlightsErrCategory theFlightErrCategory {};
完整代码示例
error_code.h
#ifndef ERROR_CODES_H
#define ERROR_CODES_H
#include <system_error>
enum class FlightsErrc {
NonexistentLocations = 10,
DatesInThePast,
InvertedDates,
NoFlightsFound = 20,
ProtocolViolation = 30,
ConnectionError,
ResourceError,
Timeout
};
namespace std {
template <>
struct is_error_code_enum<FlightsErrc> : true_type {};
}
std::error_code make_error_code(FlightsErrc);
#endif
error_code.cpp
#include "error_codes.h"
namespace {
struct FlightsErrCategory : std::error_category {
const char *name() const noexcept override;
std::string message(int ev) const override;
};
const char *FlightsErrCategory::name() const noexcept {
return "flights";
}
std::string FlightsErrCategory::message(int ev) const {
switch (static_cast<FlightsErrc>(ev))
{
case FlightsErrc::NonexistentLocations:
return "nonexistent airport name in request";
break;
case FlightsErrc::DatesInThePast:
return "request for a date from the past";
break;
case FlightsErrc::InvertedDates:
return "requested flight return date before departure date";
break;
case FlightsErrc::NoFlightsFound:
return "no filight combination found";
break;
case FlightsErrc::ProtocolViolation:
return "received malformed request";
break;
case FlightsErrc::ConnectionError:
return "could not connect to server";
break;
case FlightsErrc::ResourceError:
return "insufficient resources";
break;
case FlightsErrc::Timeout:
return "processing timed out";
break;
default:
return "(unrecognized error)";
}
}
const FlightsErrCategory theFlightErrCategory {};
}
std::error_code make_error_code(FlightsErrc errc) {
return {static_cast<int>(errc), theFlightErrCategory};
}
参考内容
https://blog.csdn.net/mightbxg/article/details/108290083?app_version=5.15.4&csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22108290083%22%2C%22source%22%3A%22weixin_44708428%22%7D&utm_source=app
http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-1.html