Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Has it been established if move/copy constructor/assignment are "deleted" or "not declared" in C++17?

I was looking at this answer regarding What are the rules for automatic generation of move operations?, and am hopeful that the answer has now been well established by now.

The slide that shows what constructors/assignment operators are "not declared", "defaulted" or "deleted", based on what has been declared in the class, shows:

enter image description here

That was taken from these slides, with the red squares meaning that this behaviour is deprecated.

When compiling the following:

#include <iostream>
struct X
{
  template<typename...T>
  X(T&&...) {
    std::cout << "Yay!\n";
  }

  ~X() {}
};

int main() {
  X x0;
  X x1{x0};
  X x2{std::move(x0)};
}

It would appear that they have been "not declared", since it compiles and the output is "Yay!" three times (which is good, at least for me). But I want to confirm that I can rely on this behaviour.

Edit

It has been pointed out by Frank that, if a copy constructor is also added, it still says "Yay!" three times, which is interesting behaviour. Doing further testing, if a move constructor is added, it will only say "Yay!" twice. Can anyone explain this behaviour?

like image 984
Adrian Avatar asked May 12 '19 15:05

Adrian


People also ask

Is move constructor automatically generated?

If a copy constructor, copy-assignment operator, move constructor, move-assignment operator, or destructor is explicitly declared, then: No move constructor is automatically generated. No move-assignment operator is automatically generated.

When should you delete copy constructor?

When to delete copy constructor and assignment operator? Copy constructor (and assignment) should be defined when ever the implicitly generated one violates any class invariant. It should be defined as deleted when it cannot be written in a way that wouldn't have undesirable or surprising behaviour.

What happens when the copy constructor is declared private?

Explanation: The copy constructor can be defined as private. If we make it private then the objects of the class can't be copied. It can be used when a class used dynamic memory allocation. Explanation: The object should not be modified in the copy constructor.

How copy constructor can be declared in what situations use of copy constructor is necessary?

Copy Constructor in C++ Copy constructor is used to initialize the members of a newly created object by copying the members of an already existing object. Copy constructor takes a reference to an object of the same class as an argument.


1 Answers

According to N4659 (almost C++17 standard), they are still defined as defaulted but the behavior is (still) deprecated.

  • For the copy constructor, see [class.copy.ctor]/6:

If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted. The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

  • For the copy assignment, see [class.copy.assign]/2:

If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy assignment operator is defined as deleted; otherwise, it is defined as defaulted. The latter case is deprecated if the class has a user-declared copy constructor or a user-declared destructor.

like image 73
Oliv Avatar answered Nov 03 '22 14:11

Oliv