#include <type_traits>
struct test {
virtual void foo() noexcept = 0;
};
struct test2 : test {
void foo() noexcept override final {}
};
// fails
static_assert(std::is_move_constructible<test>::value, "test not move constructible");
// succeeds
static_assert(std::is_move_constructible<test2>::value, "test2 not move constructible");
(Live)
According to cppreference.com (and as far as I understand), test
should have an implicitly-generated move constructor:
The implicitly-declared or defaulted move constructor for class T is defined as deleted in any of the following is true:
- T [= test] has non-static data members that cannot be moved (have deleted, inaccessible, or ambiguous move constructors)
- T has direct or virtual base class that cannot be moved (has deleted, inaccessible, or ambiguous move constructors)
- T has direct or virtual base class with a deleted or inaccessible destructor
- T is a union and has a variant member with non-trivial copy constructor
- (until C++14) T has a non-static data member or a direct or virtual base without a move constructor that is not trivially copyable.
Why does the compiler not generate an implicit move constructor for test
? Any why does it do so for test2
?