如何为从特定类型派生的类型专门化模板

rel*_*xxx 5 c++ templates

我有World管理对象创建的类...在创建之后调用afterCreation方法,我创建的对象是从Entity(例如MyEntity)派生的用户定义类型,我想调用addEntity.我的对象是别的,我什么都不做. addEntity必须使用适当的调用T,因为它为每个派生类等生成唯一的ID.

这是我的解决方案:

template <int v>
struct ToType
{
    enum { value = v };
};

template <typename T>
void World::afterCreation(T * t)
{
    afterCreation(t, ToType<std::is_base_of<Entity, T>::value>());
}

template <typename T>
void World::afterCreation(T * t, ToType<true>)
{
    addEntity(t); //here I cant pass Entity *, I need the real type, eg. MyEntity
}

template <typename T>
void World::afterCreation(T * t, ToType<false>)
{

}
Run Code Online (Sandbox Code Playgroud)

我的问题是 - 可以做得更好吗?

如何在没有ToType或类似的情况下模拟以下代码?

template <typename T>
void afterCreation(){/*generic impl*/}

template <typename T where T is derived from Entity>
void afterCreation(){/*some specific stuff*/}
Run Code Online (Sandbox Code Playgroud)
  • 标题中的"专门化"只是为了描述我的意图,不需要用模板专业化来解决问题

Dav*_*eas 3

它不会让它变得更好,但您可以使用 SFINAE 删除一级间接:

template <typename T>
typename std::enable_if< std::is_base_of<Entity, T>::value >::type
 World::afterCreation(T * t)
{
   // Derived from Entity
}
template <typename T>
typename std::enable_if< !std::is_base_of<Entity, T>::value >::type
 World::afterCreation(T * t)
{
   // generic
}
Run Code Online (Sandbox Code Playgroud)

这是如何运作的?当编译器找到对其的调用时,它afterCreation会尝试确定哪个重载是最好的,并为此匹配类型并尝试执行替换。在这两种情况下,匹配类型(来自参数)并将替换应用于整个表达式。如果作为第一个参数传递的值是,则模板enable_if包含内部类型,否则模板不包含此类类型。在类型替换期间,其中一个重载将产生无效的函数签名(条件为 false 的函数签名),并将从候选集中删除。typetrue