Reputation: 158
I have a question as I cannot explain why something works where I probably have made a mistake. Maybe somebody kind can help me to improve my C++ culture by explaining to me why this is so.
For better transparency I simplifiy the code quite a bit.
I have a template virtual class that is like this:
template<class Node>
class tXmlNode
{
public:
tXmlNode();
virtual ~tXmlNode();
protected:
Node* node;
}
;
From this I derive several classes.
Mostly I derive from it another template class such as this one:
template<class Part>
class tXmlMove : public tXmlNode<Part>
{
public:
tXmlMove(Part* part);
~tXmlMove();
protected:
int n_translate;
};
with this implementation (reduced to the constructor):
template<class Part>
inline tXmlMove<Part>::tXmlMove(Part* part) : tXmlNode<Part>(part)
{
//do some construction
}
;
As you can see I delegate some part of the construction to the parent class constructor. Works fine.
Now I have another derived class but which is derived from a specialized parent class (the specialisation is a self-specialisation but from other classes with similar specialized parent it works exactly as for this one):
class tXmlCaseDefinition : public tXmlNode<tXmlCaseDefinition>
{
public:
tXmlCaseDefinition();
tXmlCaseDefinition(const pugi::xml_node& parent);
~tXmlCaseDefinition();
protected:
int n_shapes;
}
;
(I guess it is due to the specialization that I do not need to construct this class as a template class.)
Its not-default constructor is implemented as follows:
nXml::tXmlPart::tXmlPart(
const pugi::xml_node& parent,
const int npos) : tXmlNode(parent, npos), this_id(""), this_type(""), description("")
{
}
;
As you can see I did not delegate to the parent constructor by using tXmlNode<tXmlCaseDefinition>(parent,npos)
but simply tXmlNode(parent,npos)
. I didn't pay attention to that and it works for some mysterious reason. I simply cannot understand why. Can somebody explain?
Also do I need to use tXmlNode<Part>(part)
or can I use tXmlNode(part)
instead for classes not derived from the specialized parent class or is this only possible when I have a spezialized parent?
Thank you very much!
Upvotes: 2
Views: 235
Reputation: 41090
Within the definition of a template class (more formally, the "current instantiation"), there is something called an injected-class-name, which is simply the name of the template sans arguments. For example:
template<class T>
struct Foo
{
Foo* ptr; // refers to Foo<T>
};
When you derive from a templated class, the base class' injected-class-name is inherited. Therefore you can also refer to the base class sans template arguments (assuming the name is accessible; some ancestor didn't privately inherit from it):
template<class T>
struct Base
{
};
struct Derived : Base<int>
{
Base* ptr; // refers to Base<int>
};
cppreference does a decent job of summarizing all the standardese here (Refer to [temp.local], [basic.lookup], and [basic.scope.class])
Upvotes: 5