0

我在头文件中定义了以下模板函数。

template <class T> T* spawnEnemy(SpawnDirection dir);

我的目的是创建一个通用的生成函数,它接受敌人类型作为模板参数并从函数返回生成的对象。

以下是不正确的实现,但我用它来表达我想要实现的目标。

template <class T> T* ObjectSpawner::spawnEnemy(SpawnDirection dir)
{
    if(_enemiesPool->isAnyFreeObjects())
    {
        T* enemy = NULL;
        if(typeof(T*) == Zombie01)   // This line is INCORRECT
            enemy = dynamic_cast<T*>(_enemiesPool->popFreeObjectAndAddToActiveListForType(ZOMBIE));
        else if ...

        return enemy;
    }
    else
        return NULL;
}

那就是我需要能够从T进行类型检查,所以我可以适当地调用函数

popFreeObjectAndAddToActiveListForType(int type)

以正确的值作为输入。

那么如何在模板函数中进行类型检查呢?

编辑:在得到了stephen linnvoigt的建议后,我发现这个设计有一个缺陷,但这是因为我已经将它加满了。更容易的是让函数有另一个类型参数并且不涉及模板但需要稍后转换为特定类型。无论如何,很高兴知道这种情况的解决方案。

4

2 回答 2

1

一种可能性是使用dynamic_cast,如果T是 的基类Zombie01

T *enemy = dynamic_cast<Zombie01*>(x);
if (!enemy)
{
   // x can not cast to Zombie01
   // do something else
}

但是,建议尽量减少使用dynamic_cast

另一个想法是使用std::is_same

如果 T 和 U 以相同的 const-volatile 限定命名同一类型,则提供等于 true 的成员常量值。否则值为假。

但是,我正在尝试使用来自 Effective C++ 的 Scott Meyers 的提示:

“任何时候你发现自己在编写“如果对象是 T1 类型,那么做某事,但如果它是 T2 类型,那么做其他事情”形式的代码,”打自己一巴掌。

于 2013-03-03T21:56:46.597 回答
1

你想要这样的东西(使用类型特征):

以下代码部分必须放在类部分之外。

template <typename T>
struct EnemyTraits { };

template <>
struct EnemyTraits<Zombie01> { static const int pop_type = ZOMBIE; };

template <>
struct EnemyTraits<Vampire01> { static const int pop_type = VAMPIRE; };

应按照this中的建议在头文件中定义以下函数。

template <typename T> T* ObjectSpawner::spawnEnemy(SpawnDirection dir)
{
    if(_enemiesPool->isAnyFreeObjects())
    {
        const int pop_type = EnemyTraits<T>::pop_type;
        return dynamic_cast<T*>(_enemiesPool->popFreeObjectAndAddToActiveListForType(pop_type));
    }
    else
        return NULL;
}
于 2013-03-03T21:58:46.703 回答