The container was really just something I could set up quickly to show how the AddComponent method would work internally in this scenario.
Whether or not it's better to have a separate container is hard to say - it depends on the context of your application and how you choose to model your objects. Your pattern looks to me like a hierarchical structure where each node has a map that may or may not contain some components. It might be that this is exactly what you want or need.
In terms of the template stuff, I think the interest is possibly in the call site there. What are you doing when you call GetComponent? Why do you need to care which type of component it is?
My guess is you're doing something special based on the component. If this is the case, then something might be up with the general structure here. A couple of things come to mind:
The interface is insufficient and needs extending
We've got a method that gets a Component*. If that's the public facing API in our class, then why do we want to specialise for particular component types?
If we want different components to do different things at the call site, dynamic dispatch allows this.
For example:
https://ideone.com/5y5s8p
We can retrieve the components as Component* types, call ComponentType at the call site and the output shows that we're calling into each types respective method.
The common interface isn't a good fit for the concrete types
If the dynamic dispatch above isn't suitable, then it could be that the interface (and there for your GetComponent API point) is insufficient here. Given that, aside from the method for identifying type, the commonality is the Clone method (in my opinion, a better name for your interface generally would be Cloneable or something like that), does it make sense semantically to store maps of Cloneable objects?
Even if you want both concrete types to be Cloneable, it could be that storing them all in a container as such doesn't make sense and what you actually want is stronger modelled API points for the concrete types.
Given that you're restricting to one of each type anyway, you could have something like this:
https://ideone.com/3RZstb
Admittedly, in this scenario I'd also be inclined to give Player and GameObject their own interfaces. I'm a personal fan of designing by interface - it offers a lot in terms of both flexibility and testability.
There's always the option of casting at the call site. For example (assuming you've a method that returns a Component*):
1 2
|
auto pPlayer = dynamic_cast<Player*>(someContainer.GetComponent("Player"));
assert(pPlayer != nullptr);
|
However, I think this is hideous and smells of bad design. I'd personally opt to avoid it.