【问题标题】:Does forbidding copy operations automatically forbid move operations? [duplicate]禁止复制操作会自动禁止移动操作吗? [复制]
【发布时间】:2016-09-09 18:07:31
【问题描述】:

我想编写一个没有任何复制和移动语义的 C++ 类:我只对它的构造函数和析构函数感兴趣。

我使用 C++11 的 =delete 语法明确地禁用了复制操作(即复制构造函数和复制赋值运算符),例如:

class MyClass 
{
  public:    
    MyClass()  { /* Init something */    }
    ~MyClass() { /* Cleanup something */ }

    // Disable copy
    MyClass(const MyClass&) = delete;
    MyClass& operator=(const MyClass&) = delete;
};

作为测试,我尝试在类实例上调用std::move(),似乎没有自动生成移动操作,因为 Visual Studio 2015 C++ 编译器会发出错误消息。

这是 MSVC 2015 特有的行为,还是由 C++ 标准规定,通过 =delete 复制操作自动禁用移动构造函数和移动赋值?

【问题讨论】:

标签: c++ c++11 move-semantics


【解决方案1】:

MSVC 在这种情况下符合标准。 C++14 中的 [class.copy]/9 内容如下:

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

  • X 没有用户声明的复制构造函数,
  • X 没有用户声明的复制赋值运算符,
  • X 没有用户声明的移动赋值运算符,并且
  • X 没有用户声明的析构函数。

所以你的类有 no 移动构造函数,任何移动它的尝试都会退回到已删除的复制构造函数。

【讨论】:

  • 所以,我的 "user-declared destructor" 的存在阻止了移动构造函数的自动(隐式)声明。我想知道拥有=delete 复制构造函数是否算作“用户声明的复制构造函数”
  • @Mr.C64 确实如此。如果你想要移动构造函数,你可以显式地默认它。或者你可以尝试遵守零规则。
【解决方案2】:

虽然布赖恩可能为你提供了你关心的信息,但让我试着再补充一点(或者也许只是以一种没人关心的方式迂腐地措辞)。 p>

删除复制构造函数或复制赋值运算符可防止编译器隐式合成移动构造函数/移动赋值运算符。

您仍然可以自己显式定义移动构造函数和/或移动赋值。因此,防止复制实际上并不能防止移动构造和移动赋值——它只是防止编译器隐式实现它们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多