I know there is a lot of these "cannot convert argument" questions here, but I promise I looked around a lot and I think my particular case hasn't been asked yet, plus I have tried debugging this for quite a few hours but can't seem to get it.
Basically, I am creating a Component system for a 2D game engine. I have separated my logic into two parts: Component
and ComponentSystem
. The Component
class will store only data, while the ComponentSystem
will update and manipulate that data accordingly.
The ComponentSystem
base class is abstract with a template to specify which Component
the system will be using. Here is the .h file:
// =================================================================================================
// == COMPONENT SYSTEM CLASS =======================================================================
// =================================================================================================
template <class T>
class ComponentSystem
{
public:
// -- ctor & dtor
ComponentSystem<T>();
~ComponentSystem<T>();
// -- update components
virtual void UpdateComponents(float dt) = 0;
// -- populates the components of this systems
virtual void PopulateFromCurrentLevel() = 0;
// -- clears the components of this system
virtual void ClearFromCurrentLevel() = 0;
protected:
// -- actual list of components
std::vector<T*> components;
};
I then also have a SpriteComponentSystem
, which derives from ComponentSystem
, but with the SpriteComponent
as the template type:
class SpriteComponentSystem : public ComponentSystem<SpriteComponent>
{
public:
SpriteComponentSystem();
~SpriteComponentSystem();
virtual void UpdateComponents(float dt);
virtual void PopulateFromCurrentLevel();
virtual void ClearFromCurrentLevel();
};
Finally, in my Game
class I am storing a vector of the base class, like so:
std::vector<ComponentSystem<Component*>*> systems;
However, when I try to push a SpriteComponentSystem*
into systems
, I get the following error:
C2664 - 'void std::vector<HSZGame::ComponentSystem<HSZGame::Component *>
*,std::allocator<_Ty> >::push_back(_Ty &&)': cannot convert argument 1 from
'HSZGame::SpriteComponentSystem *' to
'HSZGame::ComponentSystem<HSZGame::Component *> *const &'
I have tried implementing a specific cast from one object to the other, and also tried doing a dynamic_cast
which worked for compile time but the object was then nullptr
at runtime.
In case anyone is wondering, SpriteComponent
does indeed inherit from Component
, which is the base class. Thanks again for your help everyone!
First of all you are initializing a std::vector<ComponentSystem<Component*>*>
that takes a ComponentSystem
with a Component*
template parameter. This means that your vector components
that is contained within ComponentSystem
is holding a pointer to a pointer to a Component
. This might be an error on your part unless you actually mean to hold a pointer to a pointer. If you don't your vector should be initialized std::vector<ComponentSystem<Component>*>
.
Secondly it seems you would like to use runtime polymorphism so that your vector systems
can hold not only ComponentSystem<Component>
objects but also SpriteComponentSystem
(AKA ComponentSystem<SpriteComponent>
objects).
Unfortunately the language does not allow this since templates are instantiated at compile time and each instantiation is its own type. The language views ComponentSystem<Component>
and ComponentSystem<SpriteComponent>
as separate types and hence the compiler is complaining.
I think you would need to rethink this design philosophy.