0

I am having trouble converting a pointer to a templated derived class to a base class pointer for the purposes of storing in a map(and obviously retrieving it later.). I have:

#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;
}

Why is that and is there a way of fixing that so I can template a class with enum values for the purposes of calling externally by a getClass<Enum> function, as is hopefully clear in the example?

Maths noob
  • 1,684
  • 20
  • 42

1 Answers1

1

The problem is simple: your redefinition of Role

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

Doesn't extend RoleBase.

Either remove it or change it to:

template<> class Role<RoleEnum::Player> : public RoleBase {}
Pedro Boechat
  • 2,446
  • 1
  • 20
  • 25
  • ha! Why does the compiler not warn me about my incorrect template specialization then! Any guesses how these roles are being interpreted by the compiler? – Maths noob Nov 05 '16 at 14:30
  • 1
    Templates are instantiated when you use them, and when a template is instantiated it's [memoized](https://en.wikipedia.org/wiki/Memoization). – Pedro Boechat Nov 05 '16 at 14:32
  • If you specialize a template, the compiler is going to use your definition instead of creating a new definition on his own. – Pedro Boechat Nov 05 '16 at 14:49