2016-11-05 7 views
0

マップに格納する目的でテンプレートの派生クラスへのポインタを基本クラスのポインタに変換する際に問題があります。私が持っている:C++:派生したテンプレートクラスとベースクラスの間のダウンキャストとアップキャスティング?

#include <map> 
//Role.h 
class RoleBase{}; 
enum class RoleEnum : int; 

template<RoleEnum role> 
class Role : public RoleBase{}; 

//Relationship.h 
class Relationship{ 
public: 
    template<RoleEnum role> 
    Role<role>* getRole(){ 
    auto it=RoleMap.find(role); 
    if (it == RoleMap.end()) { 
     return nullptr; 
    } else { 
      RoleBase* roleBase= it->second; 
      return static_cast<Role<role>* >(roleBase); 
     } 
    } 
    std::map<RoleEnum,RoleBase*> RoleMap; 
}; 

//squash.h 
enum class RoleEnum : int 
{ 
    Player, 
    Referee 
}; 

template<> class Role<RoleEnum::Player>{}; 
template<> class Role<RoleEnum::Referee>{}; 

class SquashGame: public Relationship{ 
public: 
    SquashGame(){ 
     RoleBase* playerRole=new Role<RoleEnum::Player>; //problematic 
     RoleMap.emplace(RoleEnum::Player,playerRole); 
    } 
}; 

int main() { 
    SquashGame squashGame; 
    squashGame.getRole<RoleEnum::Player>(); 
    return 0; 
} 

なぜそれがあるとの例では、うまくいけば明らかであるように、私は、getClass<Enum>機能により外部からの呼び出しのために列挙値を持つクラスをテンプレート化できることを固定する方法はありますか?

答えて

1

問題は単純です:役割

template<> class Role<RoleEnum::Player> {} 

のあなたの再定義はRoleBaseを拡張しません。

それを削除するか、それを変更するか:

template<> class Role<RoleEnum::Player> : public RoleBase {} 
+0

ヘクタール!なぜコンパイラは間違ったテンプレートの特殊化について私に警告しないのですか?いずれも、これらの役割がコンパイラによってどのように解釈されているかを推測します。 – ShS

+1

テンプレートは使用時にインスタンス化され、テンプレートがインスタンス化されると[memoized](https://en.wikipedia.org/wiki/Memoization)になります。 –

+0

テンプレートを特殊化すると、コンパイラは自分で新しい定義を作成するのではなく、その定義を使用します。 –

関連する問題