在 =delete 的含义中使用 =default

Using =default in meaning of =delete

下面的代码编译的很好:

struct B { 
    B(int) {} 
};

struct D : B {
    D() = default;
};

直到我必须创建一个实例 class D:

D d; // error: use of deleted function 'D::D()'

D 的构造函数实际上作为 = delete; 工作时,是否有任何理由(用例)允许 = default

g++ 在错误中给出了很好的解释:

bla.cpp:6:5: note: ‘D::D()’ is implicitly deleted because the default definition would be ill-formed: D() = default;

默认构造函数将尝试构造 D 的所有部分。你没有字段,但它有一个初始的 B - 它没有空构造函数,只有一个 int 一个。

默认行为是有意义的 - D 不应该有一个空的构造函数,除非它明确说明用哪个 int 来构造 B,而编译器不需要猜测。否则你将有一个 D 对象,并且根据 B 构造函数中发生的情况 B 可能包含垃圾,例如,如果初始化一个字段。

当你问为什么这是“allowed”时,我不确定你的问题是否是字面意思,因为 B 默认构造函数已被删除,但我可以想到两个原因:

  1. 此行为定义明确,没有理由禁止它。无论如何,仅当您尝试非法构造某些东西时才检测到错误。
  2. 它更灵活 - 将 B 更改为具有默认构造函数将自动允许 D 具有默认构造函数。

Is there any reason (use case) to allow = default for D's constructor, when it's actually works as = delete;?

它不像 =delete 那样工作。它说的正是它应该说的。您明确希望编译器生成默认实现。

正好编译生成的一个要定义删除。因为B的默认构造函数被隐式删除了

B 有一个非默认构造函数(它的构造函数接受一个没有默认值的参数)。

派生的 D class 因此没有默认构造函数,其默认构造函数被删除(因为编译器无法为 D 生成可以调用B(int) 其父 class 的构造函数。)

D() = default; 只是说你想要 D 的默认构造函数,并且如上所述,默认构造函数被删除。