【发布时间】:2018-12-21 11:02:30
【问题描述】:
由于B 基类子对象在A 构造函数中的复制构造,以下代码无法同时使用Gcc 和Clang 编译:
struct B{
B();
B(const B&) =delete;
};
struct A:B{
A():B(B()){} //=> error: use of deleted function...
};
不过根据[class.base.init]/7:
mem-initializer 中的 expression-list 或 braced-init-list 用于初始化指定的子对象(或者,在委托构造函数的情况下,完整的类对象)根据[dcl.init]的初始化规则进行直接初始化。
因此,对于成员或直接基类,初始化规则是相同的。对于成员子对象,Gcc 和 Clang 不使用已删除的复制构造函数:
struct A2:B{
B b;
A2():b(B()){} //=> OK the result object of B() is b
};
这不是 Clang 和 Gcc 的编译器错误吗? B的复制构造函数不应该在A()中省略吗?
有趣的是,即使 gcc 检查复制构造是否格式正确,它也会忽略此复制构造函数调用,请参阅 assembly here
【问题讨论】:
-
Nice Q...你是否对空白感到烦恼?
-
@YSC Whitespace 不再是我的首选编程语言了!
-
我将“委托构造函数”解析为委托构造函数。如,委托给同一类的另一个构造函数,而不是基类的构造函数。所以我看不到引用的子句如何应用于基类。
-
@SamVarshavchik 你应该寻找suboject的定义!
-
@xskxzr 确实在回答我的问题。
标签: c++ language-lawyer c++17