Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does a Node pointer in a Node class not need template arguments (e.g. in linked lists)? [duplicate]

Tags:

c++

templates

the code comes from a C++ book as below:

Why does this public member Link* next have no typename argument?

template <typename E> class Link {
private:
    static Link<E>* freelist;
public:
    E element;
    Link* next;  // this line confused me....

    Link(const E& elemval, Link* nextval = NULL)
    {
        element = elemval; next = nextval;
    }
    Link(Link* nextval = NULL) { next = nextval; }
    void* operator new(size t){
        if (freelist == NULL) return ::new Link;
        Link<E>* temp = freelist;
        freelist = freelist->next;
        return temp; // Return the link
    }
};

I think it should be Link<E>* next.

Please tell me the reason it doesn't have a template argument.

like image 832
Makoto Avatar asked Nov 20 '22 16:11

Makoto


1 Answers

This is known as the "injected class name." The rule specifically comes from [temp.local]:

Like normal (non-template) classes, class templates have an injected-class-name (Clause 9). The injected-class- name can be used as a template-name or a type-name. When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it refers to the class template itself. Otherwise, it is equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.

Within the scope of a class template specialization or partial specialization, when the injected-class-name is used as a type-name, it is equivalent to the template-name followed by the template-arguments of the class template specialization or partial specialization enclosed in <>. [ Example:

template<template<class> class T> class A { };
template<class T> class Y;
template<> class Y<int> {
    Y* p;                                // meaning Y<int>
    Y<char>* q;                          // meaning Y<char>
    A<Y>* a;                             // meaning A<::Y>
    class B {
        template<class> friend class Y;  // meaning ::Y
    };
};

—end example ]

This is basically for convenience, so that the class name within the class refers to the class itself and not anything external which may have the same name. For class templates, it potentially saves a lot of typing if you have a long template argument list.

like image 97
Barry Avatar answered Dec 21 '22 22:12

Barry