首页 > 解决方案 > 如何使用完全限定名继承基类的构造函数?

问题描述

假设我有以下课程:

class foo : public std::runtime_error
{};

要将 的构造函数std::runtime_error引入我的班级,您会认为我可以这样做:

using std::runtime_error::std::runtime_error;

但是,这不起作用。通常我会考虑这样做:

using super = std::runtime_error;
using super::super;

这确实有效,但不确定这是一种解决方法还是唯一真正的解决方案。在使用 Clang 进行测试后,这有效:

using runtime_error::runtime_error;

但是我很好奇为什么这行得通,因为它不是完全合格的。为了解决这个问题,我尝试通过引入多重继承来打破它:

namespace n
{
    class runtime_error {};
}

class foo : public std::runtime_error, public n::runtime_error
{
public:
    using runtime_error::runtime_error;
};

现在using runtime_error::runtime_error不再起作用了,因为它是模棱两可的。但是,super别名仍然有效(因为您明确地选择了要继承的基类),但是如果您必须为每个继承的类型(例如super1super2)定义别名,则可能会变得讨厌。

当完全限定名称语法( using ::)与::用于指定成员构造函数的定义不明确时,从位于不同命名空间中的基类继承构造函数的正确方法是什么?

标签: c++

解决方案


尝试using std::runtime_exception::std::runtime_exception在类中使用时出现编译错误的原因是您需要提供构造函数的名称。并且构造函数的名称std::runtime_exception不是std::runtime_exception,它是runtime_exception- 构造函数的名称是非限定类型。因此,正确的符号是

using std::runtime_exception::runtime_exception;

您使用类型别名的其他解决方案也可以工作,尽管起初它可能看起来令人困惑 - 为什么它与类型别名一起工作,当类型别名确实是std::runtime_exception- 记住类型别名不是文本替换是有帮助的,因此它可以工作正如预期的那样。

这两种方法都是有效的,选择哪一种完全取决于您和您的代码。


推荐阅读