class A {
public:
A() = default;
A(const A&) = delete;
A(A&&) = delete;
};
class B {
public:
B() = default;
B(const B&) = default;
B(B&&) = default;
A a_;
};
int main() {
B b{};
static_cast<void>(b);
}
为什么要编译?复制构造函数不应具有默认定义,因为A
具有已删除的拷贝构造函数。
在这种情况下,默认副本构造函数意味着什么?
我在这里想念什么?
答案 0 :(得分:2)
将特殊成员声明为默认成员不会 not 表示存在可用的定义。相反,= default
的意思是“在这里填写合理的含义”,这也意味着如果这是唯一合理的事情(例如,如果类成员不可复制),则该成员最终被定义为已删除。 / p>
确切的规则在[class.copy.ctor]中:
[...]如果
X
具有以下条件,则将类X
的默认复制/移动构造函数定义为已删除(9.4.3):
- 可能被构造的子对象类型
M
(或其数组),由于用于查找M
的对应构造函数的重载分辨率(11.3)导致模棱两可或从默认构造函数中删除或无法访问的函数,- [...]
也就是说,您的B::B(const B&)
最终被定义为已删除。尝试制作b
的副本时,您会注意到这一点。
答案 1 :(得分:1)
这里的默认值表示我认为是删除。有人需要查找标准文档以进行确认。但是,如果您在main()
中添加了一行B foo = b;
,那么我肯定会开始出现编译器错误。尽管将default
关键字用于复制ctor,您仍将无法复制B。
编辑:这是我尝试复制B
时遇到的错误。
“ B :: B(const B&)”被隐式删除,因为默认定义 会格式错误