Почему класс с явно объявленным конструктором перемещения не выполняет std::is_move_constructible_v?
Библиотека, которую я использую, требует, чтобы классы, используемые с ее шаблонами, могли быть перемещаемыми и назначаемыми по различным внутренним причинам. Я написал класс и дал ему явный конструктор перемещения.
#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(®istry) {}
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
Что я пропустил? Это действительно озадачивает, и я не могу найти в Интернете ничего о том, почему класс с явно объявленным конструктором перемещения может не быть конструктивным для перемещения. Потому что это абстрактный класс? Любая помощь будет принята с благодарностью.
1 ответ
is_move_constructible
основан на поведении is_constructibe
; это простоis_constructible<T, T&&>
. А такжеis_constructible<T, ...>
требует, чтобы вы могли это сделать:
T t(...);
Конечно, для абстрактного класса вы не можете этого сделать. Следовательно, никакой абстрактный класс не может быть "конструктивно перемещаемым" настолько, насколькоis_move_constructible
обеспокоен.