Why class derived from non-movable class is itself move constructible?

Viewed 122

According to cppreference, deriving from a non-movable class should make a derived class non-movable, too. Then why does std::is_move_constructible_v return true for the derived class?

class NonMovable{
    public:
        NonMovable(const NonMovable&) = default;
        NonMovable(NonMovable&&) = delete;
        
        NonMovable& operator = (const NonMovable&) = default;
        NonMovable& operator = (NonMovable&&) = delete;
        
        NonMovable() = default;
};

class Derived : public NonMovable{};

int main(){
    std::cout << std::is_move_constructible_v<NonMovable> << "\n"; // 0
    std::cout << std::is_move_constructible_v<Derived> << "\n"; // 1
}
1 Answers

The key clause appears to be the following:

Copy/move constructors [class.copy.ctor]

...

A defaulted move constructor that is defined as deleted is ignored by overload resolution. [ Note: A deleted move constructor would otherwise interfere with initialization from an rvalue which can use the copy constructor instead. — end note ]

Emphasis mine. The deleted move constructor is simply excluded from overload resolution, and the derived class's constructor ends up seleting the base class's copy constructor instead of the move constructor.

Related