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)

入力として正しい値を使用します。

では、このような状況でテンプレート関数内で型チェックを行うにはどうすればよいですか?

編集:スティーブン・リンとnvoigtから提案を受けた後、このデザインには欠陥があることがわかりましたが、それは私がすでに持っているものからそれを補充しているためです。より簡単なのは、関数に別のパラメーターを持たせ、テンプレートに関与させないようにすることですが、後で特定の型にキャストする必要があります。とにかく、この状況の解決策を知ることは良いことです。

4

2 に答える 2

1

の基本クラスが:のdynamic_cast場合、1つの可能性はを使用することです。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です。

ただし、EffectiveC++のScottMeyersのヒントを使用しようとしています。

「オブジェクトがタイプ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; };

こので提案されているように、次の関数をヘッダーファイルで定義する必要があります。

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 に答える