c++ - 继承默认构造函数在 gcc 中失败,但在 clang 中有效,哪个有 bug?

标签 c++ c++11 inheritance g++ clang++

举这个简单的例子。

struct Base {
    // Base::Base() defined by the compiler
};

struct Derived: Base { 
    using Base::Base; // Should inherit Base::Base()

    Derived(int value):
        m_value(value)
    {}

private:
    int m_value; // If Base::Base() is invoked, it's default constructed
};

Derived t;

据我通过阅读 cppreference 了解到的, Derived应该继承默认的Base::Base()构造函数和上面的代码应该可以顺利编译。

编辑:我的错,我链接到的页面讲述了完全相反的故事。所以,clang 似乎出现了回归。

但是,我尝试过的所有 gcc 版本都失败了,提示 Derived没有默认构造函数,而 clang 则可以,但仅从版本 3.9.0 开始; g++-7 段错误,甚至 1

你可以在godbolt上自行查看.

那么,这是谁的错呢? Clang 允许它,还是 gcc(排除段错误)不允许它?


1 虽然似乎只在 godbolt 上这样做,但我无法在本地重现段错误。

最佳答案

首先,编译器段错误始终是编译器错误。您应该报告这一点。

其次,默认构造函数永远不会被继承。来自N3242(N3797中的措辞类似),[class.inhctor]:

For each non-template constructor in the candidate set of inherited constructors other than a constructor having no parameters or a copy/move constructor having a single parameter, a constructor is implicitly declared with the same constructor characteristics unless there is a user-declared constructor with the same signature in the class where the using-declaration appears.

Base 的默认构造函数不会继承到 Derived 中,因此 Derived t 应该是格式错误的,因为没有有效的构造函数采用零参数。


在 C++17 中,尽管措辞不同,但这仍然是错误的。还是 [class.inhctor],来自 N4618:

When a constructor for type B is invoked to initialize an object of a different type D (that is, when the constructor was inherited (7.3.3)), initialization proceeds as if a defaulted default constructor were used to initialize the D object and each base class subobject from which the constructor was inherited, except that the B subobject is initialized by the invocation of the inherited constructor.

要调用 Base::Base(),我们必须从 Derived::Derived() 开始。但没有 Derived::Derived()

关于c++ - 继承默认构造函数在 gcc 中失败,但在 clang 中有效,哪个有 bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42029637/

相关文章:

c++ - 将一段代码包装成一个编译时值

c++ - 为什么标准区分直接列表初始化和复制列表初始化?

inheritance - EF4.1 Exception creating Database with table-per-hierarchy 继承

c++ - 如何在 C++ 中加入 strcpy

c++ - 使用 C++ 在 Arduino 上编写复杂的程序。如何正确使用对象或更好地使用普通 C?

c++ - 复制构造函数和抛出表达式

c++11 - std::numeric_limits::quiet_NaN() 与 std::nan() 与 NAN

c++派生类更改基类指针

c++ - 如何删除继承的私有(private) char* 属性? (例如 : in a destructor)

C++ 使用 loadbuffer 和 runbuffer 链接和运行 LuaJit 编译文件