4

I know that when I define an empty class and provide no declarations at all, the compiler will provide definitions for the default and copy constructor, destructor and copy assignment operator.

What are the rules for that? When does the compiler not provide a, say, copy constructor? What about the move constructor and move assignment operator?

(Example: The compiler will not provide definitions for any assignment operator if my class has a reference member like int&. When else will something like this happen?)

Xeo
  • 129,499
  • 52
  • 291
  • 397
  • Will this help you? https://en.wikipedia.org/wiki/C%2B%2B11#Explicitly_defaulted_and_deleted_special_member_functions – Tamer Shlash Dec 23 '11 at 22:15
  • 2
    @Mr.TAMER: Wikipedia is nice and all, but I'd like to have a complete list on SO and preferrably with standard quotes. :) Also, the Wikipedia article doesn't say anything about when you get move constructors and when the copy ctor / assignment op will not be provided. – Xeo Dec 23 '11 at 22:19
  • 1
    Will it not provide the assignment operator even if you have a reference member. An attempt to use this will generate a compilation not because it is not there but because it is invalid. – Martin York Dec 23 '11 at 22:29
  • 6
    How are we supposed to answer this without typing out large chunks of chapter 12 of the standard? It's all there and it's a pretty clear part of the standard. – CB Bailey Dec 23 '11 at 22:41
  • 3
    "I know that when I define an empty class and provide no declarations at all, the compiler will provide definitions for the default and copy constructor, destructor and copy assignment operator.". This is incorrect. It will only provide *declarations* of those. And *definitions* only if needed. – Johannes Schaub - litb Dec 23 '11 at 22:42
  • 2
    @Xeo no those are not formalities. If you were to have `struct A { void operator=(int); operator int(); int &x; }; A a{*new int}, b{*new int};` if you then say `a = b;` it will give an *error* because it *does* provide a declaration for copy assignment. If it would not, it would *not* be an error but it would convert `b` to `int`. – Johannes Schaub - litb Dec 23 '11 at 22:44
  • @Johannes: Good, one thing I didn't know! :) – Xeo Dec 23 '11 at 22:47
  • 1
    @Charles: Not everyone has access to the standard, and even if that part is pretty clear, I think SO would benefit from having a listing of those rules. – Xeo Dec 25 '11 at 09:29

1 Answers1

2

Edit: In C++11 it's more complicated than implicitly declared or not. They can either be implicitly declared and defaulted, implicitly declared and deleted, or undeclared. Read this to distinguish the latter 2. The following information isn't entirely correct since it doesn't distinguish declared and deleted vs undeclared.

The following is a work in progress. (?) indicates I would like to clarify or quantify the statement.

Special Member Functions §12/1

The implementation will implicitly declare these member functions for some class types when the user does not explicitly declare them:

  • default constructor
  • copy constructor
  • copy assignment operator
  • move constructor
  • move assignment operator
  • destructor

A special member function will NOT be implicitly declared if the type has a...


Default Constructor §12.1/5


Copy Constructor §12.8/8, §12.8/12

  • user-declared move constructor
  • user-declared move assignment operator
  • non-static data member of rvalue reference type
  • variant member with a non-trivial copy constructor and is a union-like class (?)
  • non-static data member of type (or array thereof) that cannot be copied
  • direct or virtual base class without accessible copy constructor

*Such an implicit declaration is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor (?)


Copy Assignment Operator §12.8/19, §12.8/24

  • user-declared move constructor
  • user-declared move assignment operator
  • a variant member with a non-trivial copy assignment operator and is a union-like class (?)
  • non-static data member of const non-class type (or array thereof)
  • non-static data member of reference type
  • non-static data member with inaccessible copy assignment operator
  • direct or virtual base class with inaccessible copy assignment operator

*Such implicit declaration is deprecated if the class has a user-declared copy constructor or a user-declared destructor (?)


Move Constructor §12.8/10, §12.8/12

  • user-declared copy constructor
  • user-declared copy assignment operator
  • user-declared move assignment operator
  • user-declared destructor
  • move constructor would not be implicitly defined as deleted (?)
  • variant member with a non-trivial move constructor and is a union-like class (?)
  • non-static data member of type (or array thereof) that cannot be moved
  • non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable
  • direct or virtual base class without accessible move constructor

Move Assignment Operator §12.8/21, §12.8/24

  • user-declared copy constructor
  • user-declared move constructor
  • user-declared copy assignment operator
  • user-declared destructor
  • move assignment operator would not be implicitly defined as deleted (?)
  • a variant member with a non-trivial move assignment operator and is a union-like class (?)
  • non-static data member of const non-class type (or array thereof)
  • non-static data member of reference type
  • non-static data member with inaccessible move assignment operator and is not trivially copyable
  • direct or virtual base class with inaccessible move assignment operator and is not trivially copyable

Destructor §12.4/4

Community
  • 1
  • 1
David
  • 27,652
  • 18
  • 89
  • 138