c++ - 解决 C++ 中缺乏模板化虚函数的问题

标签 c++ c++11 templates

我不确定如何最好地表述这个问题,但我并不是在问如何实现模板化虚函数本身。我正在构建一个实体组件系统,我有两个重要的类 - WorldEntity . World 实际上是一个抽象类,实现(我们称它为 WorldImpl )是一个模板化类,允许使用自定义分配器(可以与 std::allocator_traits 一起使用)。

组件是我们可以附加到实体的任何数据类型。这是通过调用名为 assign 的模板函数来完成的。在实体上。

这就是问题所在:我试图让实体在创建和初始化组件时使用世界的分配器。在一个完美的世界里,你会调用 Entity::assign<ComponentType>( ... )这会问 WorldImpl使用任何合适的分配器创建组件。然而,这里有一个问题——该实体有一个指向 World 的指针。据我所知,模板化虚函数是不可能的。

这里有更多的插图可能会使问题更加明显:

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
  }
};

既然上面的代码实际上是不可能的,那么真正的问题是:对于这样的类层次结构,我必须做些什么黑魔法才能使用 ComponentType 和 Allocator 模板调用某些函数参数?这是最终目标 - 一个在某些对象上调用的函数,两个模板参数都可用。

最佳答案

我会说实体属于某种世界,并使它们成为带有世界参数的模板。然后你可以忘记所有的继承和虚拟,只实现满足所需接口(interface)的世界,例如

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

  World world;
};

template<typename Allocator>
class WorldI
{
  template<typename ComponentType>
  ComponentType* createComponent(/* ... */)
  {
    // do something with Allocator and ComponentType here
  }
};

关于c++ - 解决 C++ 中缺乏模板化虚函数的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40288494/

相关文章:

c++ - 编写一个 Lambda 函数,将 'remembers' 值传递给它

c++ - 这个模板解析冲突叫什么?

c++ - 带有运算符 ">>"的 typedef 是什么意思?

c++ - 在运行时重写相同的类方法 C++

c++ - 在 main.cpp 之外使用 QQuickView

c++ - 为什么 O(2^n) 不同于 O(2^(n/2))?

c++ - libwebsockets 与 WebSockets++

c++ - 克服 n^2 运行时程序

c++ - 模板引用折叠删除 const 引用返回类型的 cv 限定符

c++ - 类模板静态成员初始化两次