对于我当前的项目,我定期定义要捕获的自定义异常。
但是,我正在努力确定关于这些异常的定义的最佳代码结构。
最初,我只是定义了嵌套在我的类中的引发它们的异常,就像这样:
class Foo {
struct CustomException : public std::runtime_error {
}
void TrySomething() {
throw CustomException();
}
};
但是,现在我正在使用模板类,如果不提供模板参数,则无法访问此异常。也就是说,我不能做:
template class <T>
class Foo {
struct CustomException : public std::runtime_error {
}
void TrySomething() {
throw CustomException();
}
};
void SomeFunction() {
try {
Foo foo;
foo.TrySomething();
}
catch (const Foo::CustomException& exc) {
}
}
因为没有模板参数的Foo不是类。 我正在尝试找出最干净的解决方案是什么(可以对项目的其余部分进行重新设计以遵循选定的标准)。
想到的选项:
答案 0 :(得分:0)
如果您的异常确实与模板类有着千丝万缕的联系,但是独立于模板的特定实例,则使用类似模式
struct FooBase
{
struct FooBaseException : public std::exception
{
};
};
template class <T>
struct Foo : FooBase
{
};
是一种方式。空基类优化将适用,并且至少从概念上讲,您已经引入了模板实例化之间的某些关系。
展望未来,您可能会发现常见功能出现在基类中。
这种模式在1990年代很普遍,模板可能会导致代码膨胀,但在这种情况下,我也看到了这种用法。
答案 1 :(得分:0)
我真的不明白为什么您需要为异常做模板。 我相信该代码将满足您的所有需求。您可以为经常使用的异常创建枚举,也可以引发单个自定义异常。
enum class ErrorCode {
kErrorOne,
};
// Helper function to get an explanatory string for error
inline std::string GetErrorString(ErrorCode error_code) {
switch (error_code) {
case ErrorCode::kErrorOne:
return "Some error";
}
return {};
}
class CustomException : public std::runtime_error {
public:
explicit CustomException(ErrorCode error_code) : std::runtime_error{GetErrorString(error_code)} {}
CustomException(const std::string& what)
: std::runtime_error{what} {}
};
此外,您可以在这里查看a pretty similar question