【发布时间】:2015-11-09 00:27:58
【问题描述】:
跟进this question about multiple (virtual) inheritance,我想询问一个简单的 MWE,它让 g++ 5.2.0 不安,而 clang++ 3.6.2 处理得很好,完全没有抱怨,即使设置了-Wall 和-Wextra。这是 MWE:
class Z {};
class A : virtual Z { protected: A() {} };
class B : virtual Z { protected: B() {} };
class C : A, B { public: C() : A{}, B{} {} };
int main() { C c{}; return 0; }
与 clang++ 不同,g++ 的抱怨如下:
gccodd.c++: In constructor ‘C::C()’:
gccodd.c++:2:34: error: ‘A::A()’ is protected
class A : virtual Z { protected: A() {} };
^
gccodd.c++:4:39: error: within this context
class C : A, B { public: C() : A{}, B{} {} };
^
gccodd.c++:3:34: error: ‘B::B()’ is protected
class B : virtual Z { protected: B() {} };
^
gccodd.c++:4:39: error: within this context
class C : A, B { public: C() : A{}, B{} {} };
^
用旧形式替换 C 构造函数中的统一初始化虽然效果很好,但 clang++ 和 g++ 都对以下内容感到满意:
class C : A, B { public: C() : A(), B() {} };
这产生了两个明显的选择:
- 代码在某种程度上违反了标准,导致结果未定义(即任何结果都是可以接受的)。
- 两个编译器之一存在与统一初始化和多重 + 虚拟继承相关的错误。
如果是投票问题,(1) 可能会获胜,因为 icpc 15.0.0 说明如下:
gccodd.c++(4): error #453: protected function "A::A()" (declared at line 2) is not accessible through a "A" pointer or object
class C : public virtual A, public virtual B { public: C() : A{}, B{} {} };
^
gccodd.c++(4): error #453: protected function "B::B()" (declared at line 3) is not accessible through a "B" pointer or object
class C : public virtual A, public virtual B { public: C() : A{}, B{} {} };
^
那么,是(1)还是(2)?如果是前一种情况,那我的 MWE 有什么问题?
【问题讨论】:
-
听起来像一个错误。没有理由认为这里会有 UB。
-
VC++ 14.0 也可以很好地编译它,尽管 IntelliSense 会抱怨它。
-
@0x499602D2 有趣的是,它看起来像是在尝试制作一个临时文件,然后进行复制。这也可以解释 OP 的错误。
标签: c++ c++11 inheritance gcc c++14