为什么我不能继承虚拟基的构造函数?
Why can't I inherit the constructors of a virtual base?
我正在尝试使用g++4.9.0编译以下简单代码:
struct A {
explicit A(int x) { }
};
struct B : public virtual A {
using A::A;
};
int main(int argc, char** argv) {
B b(0);
return 0;
}
但我得到以下错误:
$ g++ -std=c++11 main.cpp
main.cpp: In function ‘int main(int, char**)’:
main.cpp:10:10: error: use of deleted function ‘B::B(int)’
B b(0);
^
main.cpp:6:14: note: ‘B::B(int)’ is implicitly deleted because the default definition would be ill-formed:
using A::A;
^
main.cpp:6:14: error: no matching function for call to ‘A::A()’
main.cpp:6:14: note: candidates are:
main.cpp:2:14: note: A::A(int)
explicit A(int x) { }
^
main.cpp:2:14: note: candidate expects 1 argument, 0 provided
main.cpp:1:8: note: constexpr A::A(const A&)
struct A {
^
main.cpp:1:8: note: candidate expects 1 argument, 0 provided
main.cpp:1:8: note: constexpr A::A(A&&)
main.cpp:1:8: note: candidate expects 1 argument, 0 provided
我做错什么了吗?这是编译器错误吗?
这是一个GCC错误。§7.3.3[名称空间.udcl]/p3要求
在用作成员声明的using声明中嵌套名称说明符应命名所定义类的基类。如果这样的using声明命名构造函数,则嵌套名称说明符应命名所定义类的直接基类。。。
A
是B
的直接基,因此允许using A::A;
。
该标准规定(§12.9【class.inctor】/p8):
隐式定义的继承构造函数执行由用户编写的类的初始化具有mem初始值设定项列表的类的
inline
构造函数只有mem初始值设定项具有命名基的mem初始值设置项id在using声明的嵌套名称说明符中表示的类和下面指定的表达式列表,其中函数体中的复合语句为空(12.6.2)。如果用户编写的构造函数格式不正确,程序不正规。表达式列表中的每个表达式的形式static_cast<T&&>(p)
,其中p
是对应的构造函数参数,并且T
是p
的声明类型。
因此,相应的用户编写的构造函数是
B::B(int x) : A(static_cast<int&&>(x)) { }
其形成良好。
它似乎是用clang编译的,但不是用gcc编译的(至少在我的机器上是这样)。然而,即使使用了gcc,如果您只需向基类中添加一个explicit A()
构造函数,代码也可以编译并正常工作。
EDIT显然,正如@T.C.在评论中指出的,这是GCC中的一个已知错误。
相关文章:
- 虚拟继承基构造函数消除
- 使用回调函数从构造函数调用虚拟/派生方法的替代方法?
- 我是否需要在虚拟继承类的构造函数中初始化基类以解决菱形继承问题?
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- 使用范围解析运算符时,在构造函数中调用虚拟方法是否安全?
- 虚拟继承构造函数的组装
- C++ 虚拟继承和构造函数
- 为什么不调用虚拟基非默认构造函数,除非大多数派生基显式调用它们?
- 抽象类和虚拟构造函数的替代方案
- C 构造函数订单,而虚拟继承
- (为什么)纯虚拟派生类中是否需要虚拟基类构造函数调用?
- 使用具有虚拟多重继承的基构造函数
- 在没有限定的情况下从 T 构造函数调用类 T 的纯虚拟实现?
- C 语言设计:孩子称呼所有虚拟祖先构造函数
- 虚拟继承和默认构造函数
- 具有虚拟多重继承的构造函数定义
- 构造函数尝试调用复制构造函数,虚拟继承
- 构造函数C++中的虚拟方法
- 模拟虚拟方法的构造函数
- 在C 中的多级虚拟继承中受保护的构造函数