3

I want to write a C++ class without any copy and move semantics: I'm just interested in its constructor and destructor.

I disabled copy operations (i.e. copy constructor and copy assignment operator) explicitly using C++11's =delete syntax, e.g.:

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

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

As a test, I tried calling std::move() on class instances, and it seems that there are no move operations automatically generated, as the Visual Studio 2015 C++ compiler emits error messages.

Is this a behavior specific to MSVC 2015, or is it dictated by the C++ standard that disabling via =delete copy operations automatically disables move constructor and move assignment?

Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • 1
    see: http://stackoverflow.com/questions/37276413/default-move-constructor-assignment-and-deleted-copy-constructor-assignment – bottaio Sep 09 '16 at 18:10

2 Answers2

4

MSVC conforms to the standard in this case. [class.copy]/9 in C++14 reads:

If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared as defaulted if and only if

  • X does not have a user-declared copy constructor,
  • X does not have a user-declared copy assignment operator,
  • X does not have a user-declared move assignment operator, and
  • X does not have a user-declared destructor.

So your class has no move constructor and any attempt to move it will fall back to the deleted copy constructor.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • So, the presence of my _"user-declared destructor"_ blocks the automatic (implicit) declaration of a move constructor. I wonder if having a `=delete` copy constructor counts as a _"user-declared copy constructor"_. – Mr.C64 Sep 09 '16 at 18:16
  • 1
    @Mr.C64 indeed it does. If you want the move constructor, you can explicitly default it. Alternative you can try to conform to the rule of zero. – Brian Bi Sep 09 '16 at 18:19
2

Although Brian has probably given you the information you care about, let me try to add just a little bit more (or maybe just get pedantic about wording in a way nobody cares about).

Deleting the copy constructor or copy assignment operator prevents the compiler from implicitly synthesizing a move constructor/move assignment operator.

You can still explicitly define a move constructor and/or move assignment yourself though. So, preventing copies does not actually prevent move construction and move assignment--it just prevents the compiler from implementing them implicitly.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111