【发布时间】:2017-09-09 12:07:10
【问题描述】:
我正在使用 C 库 libusb。 libusb 方法返回libusb_error enum values 表示错误。我希望这些方法改为抛出异常。
每个 libusb 错误都有一个可以通过libusb_strerror() 函数检索的描述。我希望这是 what() 抛出异常的方法返回的内容。
我的第一次尝试涉及一个包装函数,它抛出一个带有错误描述的std::runtime_error:
libusb_error wrapper(libusb_error error) {
if(error >= 0) return error;
throw std::runtime_error(libusb_strerror(error));
}
但是使用这种方法意味着我不能只捕获 libusb 错误,也不能捕获特定的 libusb 错误。
然后我为 libusb 错误创建了 std::exception 的模板子类:
template<libusb_error error>
class LIBUSBError : public std::exception {
using std::exception::exception;
virtual const char* what() const throw() {
return libusb_strerror(error);
}
};
这种方法可以让我捕捉到特定的 libusb 错误。但是,模板参数必须是常量表达式,这要求我对包装函数中的每个枚举值使用多个语句:
// * * *
libusb_error wrapper(libusb_error error) {
if(error >= 0) return error;
if(error == LIBUSB_ERROR_IO) {
throw LIBUSBError<LIBUSB_ERROR_IO>();
}
if(error == LIBUSB_ERROR_ACCESS) {
throw LIBUSBError<LIBUSB_ERROR_ACCESS>();
}
// ... etc
}
// * * *
try {
wrapper(libusb_open(device, &handle));
} catch(LIBUSBError<LIBUSB_ERROR_ACCESS> e) {
std::cerr << e;
continue;
}
// * * *
如何在不需要我写出每个枚举值的情况下将 libusb 方法的返回值转换为 C++ 异常?
【问题讨论】:
-
您可以根据枚举值创建一个存储适当异常的地图
-
您需要为每种类型的错误单独的 catch 块吗?如果没有,在
LIBUSBError中编写一个 ctor 将接受一个参数(枚举值)并据此构造std::exception是明智的。 -
如果您仍然希望每个错误都有单独的类,请查看有关如何生成产生它们的工厂的答案:stackoverflow.com/questions/29400314/…
-
有多少个错误,它们的范围是多少?
-
@myaut 是的,每个错误我都需要一个单独的 catch 块。