继承的构造函数忽略类内初始化
Inherited constructors ignore in-class initialization
我有一个定义如下的类:
class ASTConcatenateLiteral : public ASTExpr {
using ASTExpr::ASTExpr;
private:
Type type_ = Type::nothingness(); // Type does not have a default constructor
};
这适用于 Clang。但是,GCC 给了我一条错误消息,让我认为它正在尝试使用默认的初始值设定项:
错误:调用"表情符号代码编译器::类型::类型(("没有匹配函数
如果我用这样的公共构造函数替换using ASTExpr::ASTExpr;
(ASTExpr 只提供这个构造函数(
ASTConcatenateLiteral(const SourcePosition &p) : ASTExpr(p) {}
一切正常。
根据 cppreference.com:
继承的构造函数等效于具有空主体和成员初始值设定项列表的用户定义构造函数,该列表由单个嵌套名称说明符组成,该说明符将其所有参数转发给基类构造函数。
那么为什么继承的构造函数不起作用呢?如果继承的构造函数的行为类似于用户定义的构造函数,则它应该使用为type_
提供的值,对吗?根据标准,哪个编译器是正确的?
Clang 是正确的。使用继承的构造函数时,初始化应像使用默认构造函数初始化派生类的对象一样进行,因此应使用默认成员初始值设定项。
(强调我的(
如果重载解析在初始化此类派生类的对象时选择继承的构造函数之一,则使用继承的构造函数初始化从中继承构造函数的 Base 子对象,并且 Derived 的所有其他基和成员都像默认的默认构造函数一样进行初始化(如果提供,则使用默认成员初始值设定项,否则将进行默认初始化(。
以下是标准中的一个示例:
struct B1 { B1(int, ...) { } }; struct B2 { B2(double) { } }; int get(); struct D1 : B1 { using B1::B1; // inherits B1(int, ...) int x; int y = get(); }; void test() { D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4), // then d.x is default-initialized (no initialization is performed), // then d.y is initialized by calling get() D1 e; // error: D1 has a deleted default constructor }
请注意,d.y
由默认成员初始值设定项初始化。
GCC开发人员认为这是一个编译器错误,PR67054,在GCC 7.2中得到了修复。
他们的最小例子是
struct A { A(int) {} }; struct C { C(int) {} }; struct B : A { using A::A; C c = 42; }; int main() { B b = 24; }
在线编译器可用于验证 GCC 和 clang 现在是否一致。
请注意,据我所知,在GCC 7.1中,不会生成错误的代码。尽管编译器需要默认构造函数,但永远不会调用该默认构造函数。因此,旧版本的 GCC 的可能解决方法是提供默认构造函数的声明,而不是定义。甚至可以使用属性(不是标准C++(来拒绝任何使用它的尝试:
struct C
{
#ifdef GCC_WORKAROUND_PR67054
C() __attribute__((__error__("No.")));
#endif
C(int) {}
};
- 为什么std::vector和std::valarray初始化构造函数不同
- 初始化构造函数C++中结构的向量
- C++ 中常量属性的初始化构造函数错误
- 不正确的输出和变量未用Eclipse CDT初始化构造函数
- 如何使用嵌套初始化构造函数中的一维向量初始化矩阵
- 如何通过参数初始化构造函数中的数组?
- 是否有理由使用 malloc 初始化构造函数中的指针
- 如何在 c++ 中初始化构造函数中的二维数组
- 为什么初始化构造函数列表参数时会发生异常?
- 无法初始化构造函数
- 初始化构造函数的默认参数的优选方法是什么?
- 在C++17中使用空列表初始化构造函数时发生编译错误
- C++ 初始化构造函数初始化列表中的嵌套结构?
- 初始化构造函数c++中的向量
- g++ (GCC) 4.6.0 我有以下类,我正在尝试初始化构造函数的结构成员初始化列表
- 使用字符串文本初始化构造函数中的 std::array<char,x> 成员。海湾合作委员会错误?
- 初始化构造函数C++中函数的成员指针
- 在c++中初始化构造函数中的静态成员变量时出错
- memset()初始化构造函数中的对象
- 初始化构造函数C++中的成员向量