默认移动构造函数/赋值和删除的复制构造函数/赋值

新手上路,请多包涵

根据标准,

如果类 X 的定义没有显式声明移动构造函数,当且仅当

— X 没有用户声明的复制构造函数,

— X 没有用户声明的复制赋值运算符,

— X 没有用户声明的移动赋值运算符,并且

— X 没有用户声明的析构函数。

现在以下无法编译

# include <utility>

class Foo
{
public:
  Foo() = default;
  Foo(Foo const &) = delete;
};

int main()
{
  Foo f;
  Foo g(std::move(f)); // compilation fails here
  return 0;
}

所以似乎删除的函数被认为是用户定义的,这是有道理的(它不是它的默认实现)。但是,在那种特殊情况下,如何删除复制构造函数/赋值混乱默认移动构造函数/赋值?

我认为这个问题具有实际意义,因为手动生成和 esp。维护这些默认函数很容易出错,同时(正义的)增加使用诸如 std::unique_ptr 之类的类,因为类成员使不可复制的类比过去更常见是。

原文由 P-Gn 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.4k
2 个回答

user-declared 表示 _用户提供_(由用户 定义)、 _显式默认_( = default )或 _显式删除_( = delete ) (例如您的移动构造函数)。

因此,在您的情况下, 的,移动构造函数被 隐式 删除,因为复制构造函数被 显式 删除(因此 user-declared )。

但是,在那种特殊情况下,如何删除复制构造函数/赋值混乱默认移动构造函数/赋值?

不会,但是标准并没有区分这种情况和复杂的情况。

最短的答案是, 隐式 定义的移动构造函数和 显式 删除的复制构造函数在某些情况下 可能 是危险的,当你有一个 用户定义的 析构函数而没有 用户定义的 复制构造函数时也是如此(参见 规则三/五/零)。现在,您可以争辩说用户定义的析构函数不会删除复制构造函数,但这只是语言中的一个 _缺陷_,无法删除,因为它会破坏许多旧(坏)程序。引用 Bjarne Stroustrup 的话:

在一个理想的世界里,我认为我们会决定“不生成”作为默认值,并为“给我所有常用操作”提供一个非常简单的符号。 […] 此外,“无默认操作”策略会导致编译时错误(我们应该有一种简单的方法来修复),而默认策略下的生成操作会导致直到运行时才能检测到的问题。

您可以在 N3174=10-0164 中阅读有关此内容的更多信息。

请注意,大多数人都遵循 三/五/零的规则, 我认为你应该这样做。通过隐式删除默认的移动构造函数,标准是“保护”您免受错误的影响,并且在某些情况下应该通过删除复制构造函数来保护您很长时间(参见 Bjarne 的论文)。

感兴趣的可以继续阅读:

我认为这个问题具有实际意义,因为手动生成和 esp。维护这些默认函数很容易出错,同时,(正义的)增加使用诸如 std::unique_ptr 之类的类,因为类成员使不可复制的类比过去更常见是。

将移动构造函数标记为显式默认将解决此问题:

 class Foo {
public:
  Foo() = default;
  Foo(Foo const &) = delete;
  Foo(Foo&&) = default;
};

您会得到一个具有默认移动构造函数的不可复制对象,并且在我看来,这些显式声明比隐式声明更好(例如,仅将移动构造函数声明为 default 而不删除复制构造函数)。

原文由 Holt 发布,翻译遵循 CC BY-SA 3.0 许可协议

正如你所说,从§12.8

如果类 X 的定义没有显式声明移动构造函数,当且仅当

  • X 没有 用户声明的 复制构造函数,

  • […]

注意 用户声明的.但是如果你看一下§8.4.3:

形式的函数定义:

属性说明符序列选择decl 说明符序列选择声明符 virt 说明符序列选择= 删除;

称为已删除 定义。具有已删除 定义 的函数也称为已删除函数。

隐式或显式引用已删除函数的程序,而不是 声明它,是格式错误的。

所以标准定义了 delete d 作为 用户声明的 功能(从上面可以看到),即使它们是 delete d 并且不能使用。

然后,根据 §12.8,未定义隐式移动构造函数,因为用户声明了(使用 = delete; )复制构造函数。

原文由 Rakete1111 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题