禁止复制操作是否禁止移动操作?

时间:2016-09-09 18:07:31

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

我想编写一个没有任何副本和移动语义的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复制操作自动禁用禁用移动构造函数和移动分配?

2 个答案:

答案 0 :(得分:4)

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

  

如果类X的定义没有显式声明一个移动构造函数,那么将隐式声明一个   当且仅当

时默认为      
      
  • X没有用户声明的复制构造函数,
  •   
  • X没有用户声明的副本分配运算符
  •   
  • X没有用户声明的移动赋值运算符和
  •   
  • X没有用户声明的析构函数。
  •   

因此,您的类具有 no 移动构造函数,并且任何移动它的尝试都将回退到已删除的复制构造函数。

答案 1 :(得分:2)

虽然Brian已经可能给了你所关心的信息,但是让我尝试添加一点点(或者只是以一种无人关心的方式对措辞迂腐)。

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

您仍然可以自己明确定义移动构造函数和/或移动赋值。因此,防止副本实际上并不会阻止移动构造和移动分配 - 它只是阻止编译器隐式实现它们。