为什么带有显式声明的移动构造函数的 class 会导致 `std::is_move_constructible_v` 失败?

Why is a class with an explicitly declared move constructor failing `std::is_move_constructible_v`?

出于各种内部原因,我正在使用的一个库要求 class与其模板一起使用的 es 是可移动构造和可分配的。我写了一个 class,并给它一个明确的移动构造函数。

#pragma once
#include <entt.hpp>

namespace ECS {
    //! Abstract base class for all components.
    class Component {
        friend class Transform;
    private:
        entt::registry* p_registry; //!< The registry to which this component belongs.
        entt::entity m_entity = entt::null; //!< The entity to which this component belongs.
        bool m_knownEntity = false;

        virtual void checkEntity() {
            m_knownEntity = true;
            m_entity = entt::to_entity(*p_registry, *this);
        }
    public:
        Component(entt::registry& registry) :
            p_registry(&registry) {}

        Component(Component&& old) noexcept :
            p_registry(nullptr) {
            *this = std::move(old);
        }
        virtual Component& operator=(Component&& old) {
            if (this != &old) {
                p_registry = old.p_registry;
                m_entity = old.m_entity;
                m_knownEntity = false;
            }
            return *this;
        }

        inline entt::entity getEntity() { if (m_knownEntity) { checkEntity(); } return m_entity; }
        entt::registry& getRegistry() { return *p_registry; }

        virtual void initialise() = 0; //!< Called once per component. During object creation, is called after all the object's components have been created.
        virtual void terminate() = 0; //!< Called once per component. During object destruction, is called before any of the object's components have been deleted.
    };
}

但是,这些静态断言中的第一个失败了:

static_assert(std::is_move_constructible_v<ECS::Component>, "ECS::Component isn't move constructible."); // Fails
static_assert(std::is_move_assignable_v<ECS::Component>, "ECS::Component isn't move assignable."); // Passes

我错过了什么?这真的很令人费解,而且我在网上找不到任何关于为什么带有显式声明的移动构造函数的 class 可能无法移动构造的信息。是因为它是抽象的class吗?任何帮助将不胜感激。

is_move_constructible是基于is_constructibe的行为;只是 is_constructible<T, T&&>is_constructible<T, ...> 要求您可以这样做:

T t(...);

当然,对于摘要class,这是你做不到的。因此,就 is_move_constructible 而言,没有抽象 class 可以“移动构造”。