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?