如何直接从通过模板函数传递的类型检查类型而不是从变量?

时间:2013-03-03 21:49:47

标签: c++

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

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的建议之后,我发现这个设计有一个缺陷,但这是因为我已经从我已经充实了。更容易让函数有另一个类型参数,不涉及模板但需要稍后转换为特定类型。无论如何,知道这种情况的解决方案是很好的。

2 个答案:

答案 0 :(得分:1)

一种可能是使用dynamic_cast,如果TZombie01的基类:

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。   否则值为false。

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

  

“任何时候你发现自己编写表单的代码”如果对象是   T1类型,然后做一些事情,但如果它是T2类型,那么做   别的什么,“打自己。”

答案 1 :(得分: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;
}