Consider
class Base
{};
class Derived : public Base
{};
template<typename T>
class TemplateClass
{};
Contrary to what you might think, TemplateClass<Derived>
is not a TemplateClass<Base>
in the sence of inheritance, so pointers to the former can't be implicitly converted to pointers of the later.
So why does explicitly casting a pointer to TemplateClass<Derived>
to a pointer of TemplateClass<Base>
compile? Because any pointer of a certain type may be explicitly cast to any pointer of any other type, however there are no guarantees the conversion is valid! You could for instance just as well write
int* i = (int*) new TemplateClass<Derived>;
and it would compile just fine, even though it is clearly an invalid conversion.
Now why does your example work? Sheer luck. At the point a pointer containing an address obtained through an invalid pointer cast gets dereferenced, the program becomes invalid and its bahavior undefined. Anything can happen, including doing what you would expect.
If you want TemplateClass<Derived>
to be a TemplateClass<Base>
in the sence of inheritance, you can define an specialization of TemplateClass<>
stating this relationship explicitly, like the following:
template<>
class TemplateClass<Derived> : public TemplateClass<Base>
{};