【问题标题】:Avoid c++ compiler name resolution for exception class aliases避免异常类别名的 c++ 编译器名称解析
【发布时间】:2020-10-15 14:36:16
【问题描述】:

我的代码库中定义了几个自定义异常类。这些通常继承自基本异常类型,该异常类型本身继承自 std::runtime_error。这样的异常通常不需要实现特定的行为,我只想要每个特定异常的显式类型名称。

类定义通常如下所示:

class ExceptionA : public Base
{
public:
    using Base::Base;
};
class ExceptionB : public Base
{
public:
    using Base::Base;
};

基类看起来像这样:

class Base : std::runtime_error {
public:
    Base(std::string msg)
    : runtime_error(msg)
    {}
};

现在,我讨厌重复代码来定义一个与 Base 没有区别的简单类型,所以我想将我的代码重构为 DRYer。 我的第一次尝试是通过类模板:

template<class B>
class Exception : public B
{
public:
    using B::B;
};

然后我尝试使用别名:

using ExceptionA = Exception<Base>;

typedef Exception<Base> A;

但在这两种情况下,当我遇到未捕获的异常时,编译器都会将类型名称解析为模板实例:

terminate called after throwing an instance of 'Exception<Base>'

如何通过模板实例化实际定义一种新类型?是否有更好的解决方案来避免每次都重新定义新类型。 我想用消息字符串维护 runtime_error 非平凡构造函数。

这里的最终目标是使代码更干燥,因此如果解决方案更优雅,我会接受与我完全不同的解决方案。

【问题讨论】:

  • Exception&lt;Base&gt; 实例化类型,尝试使用相同参数重新实例化模板不会创建新类型。 usingtypedef 只为类型引入替代名称,它们不会创建新类型。
  • 从您的问题中不清楚您是针对别名还是不同类型。你得到的答案是后者,无论如何更好
  • 对不起,如果问题不太清楚,我的主要目标是为以下行为提供正确的行为: - 标准异常捕获应该通过特定的异常名称而不是用于定义的模板实例来完成它 - 考虑像我展示的那样的运行时错误,错误消息不清楚这些间接指向我对语言的理解中的不同类型。

标签: c++ templates


【解决方案1】:

您可以添加标签,例如:

template <typename Tag>
class Base : std::runtime_error {
public:
    explicit Base(std::string msg) : runtime_error(msg) {}
};

using ExceptionA = Base<struct TagA>;
using ExceptionB = Base<struct TagB>;

【讨论】:

  • 谢谢 Jarod,我没有想到这一点。这当然有帮助,即使它仍然是恕我直言的一种解决方法。
猜你喜欢
  • 1970-01-01
  • 2016-07-12
  • 1970-01-01
  • 2014-07-27
  • 2020-11-25
  • 2020-07-28
  • 1970-01-01
  • 2019-06-28
  • 2015-07-31
相关资源
最近更新 更多