jeudi 27 octobre 2016

Getting around the lack of templated virtual functions in C++

I'm not sure how best to phrase the question, but I'm not asking how to implement templated virtual functions per-se. I'm building an entity component system, and I have two important classes - World and Entity. World is actually an abstract class, and the implementation (let's call it WorldImpl) is a templated class that allows use of a custom allocator (one that can be used with std::allocator_traits).

Components are any data type which we can attach to entities. This is done by calling a templated function named assign on the entity.

Here's the problem: I'm trying to make the entity use the world's allocator when creating and initializing components. In a perfect world, you would call Entity::assign<ComponentType>( ... ) which would ask the WorldImpl to create the component with whatever allocator is appropriate. There's a problem here, however - The entity has a pointer to World and templated virtual functions aren't possible to my knowledge.

Here's a bit more of an illustration that might make the issue more obvious:

class Entity
{
  template<typename ComponentType>
  void assign(/* ... */)
  {
    /* ... */
    ComponentType* component = world->createComponent<ComponentType>(/* ... */);
    /* ... */
  }

  World* world;
};

// This is the world interface.
class World
{
  // This is the ideal, which isn't possible as it would require templated virtual functions.
  template<typename ComponentType>
  virtual ComponentType* createComponent(/* ... */) = 0;
};

template<typename Allocator>
class WorldImpl : public World
{
  template<typename ComponentType> // again, not actually possible
  virtual ComponentType* createComponent(/* ... */)
  {
    // do something with Allocator and ComponentType here
  }
};

Seeing as the above code isn't actually possible, here's the real question: With a class hierarchy such as this, what black magic do I have to do in order for some function to be called with both the ComponentType and Allocator template parameters? This is the ultimate goal - a function called on some object with both template parameters available to it.

Aucun commentaire:

Enregistrer un commentaire