2

I read this:

N3337 [class.copy]/9: 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, X does not have a user-declared destructor, and the move constructor would not be implicitly defined as deleted. Declaring the destructor and defining it as default counts as user-declared.

Here: Does a default virtual destructor prevent compiler-generated move operations?

However, this code:

struct A1 { virtual ~A1() {};  };

struct B1 : public A1 {
    ~B1() override {};  };

struct A2 { virtual ~A2() = default;  };

struct B2 : public A2 {
    ~B2() override = default;  };

struct A_NO_VIRTUAL {
    ~A_NO_VIRTUAL() {};  };

struct B_NO_VIRTUAL : public A_NO_VIRTUAL {
    ~B_NO_VIRTUAL() {};  };


int main() {  std::cout << std::is_nothrow_move_constructible_v<B1> << std::is_nothrow_move_constructible_v<B2> << std::is_nothrow_move_constructible_v<B_NO_VIRTUAL> << std::endl; }

prints: 111

See: http://coliru.stacked-crooked.com/a/5c53057a1a4ce3f4

expected: 000

Why is that?

dwto
  • 278
  • 1
  • 7
  • 1
    "Types without a move constructor, but with a copy constructor that accepts const T& arguments, satisfy std::is_move_constructible. " - https://en.cppreference.com/w/cpp/types/is_move_constructible – interjay Jun 07 '23 at 20:17
  • Does this answer your question? [C++ Auto Generates Move Constructor With User Declared Destructor?](https://stackoverflow.com/questions/35239552/c-auto-generates-move-constructor-with-user-declared-destructor) – JaMiT Jun 26 '23 at 05:37

1 Answers1

5

is_move_constructible roughly checks whether MyClass x(std::move(y)); is valid. It can be valid if MyClass doesn't have a move constructor, but does have a copy constructor, which is going to be silently used in place of the move constructor.

Declaring a destructor only removes the move operations, but keeps the copy ones (the latter is deprecated).

To test this properly, add a member variable to your class, and log the calls to the member's copy and move constructors.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207