ManyQuestions
ManyQuestions

Reputation: 158

Why can I omit the template parameter specification in some cases?

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

Answers (1)

AndyG
AndyG

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

Related Questions