我不确定如何最好地表述这个问题,但我并不是在问如何实现模板化虚函数本身。我正在构建一个实体组件系统,我有两个重要的类 - World
和 Entity
. 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/