在没有模板参数的类模板中使用类名

14

以下代码来源于C++书籍:

为什么这个公共成员Link* next没有类型参数?

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
    }
};

我认为应该是 Link<E>* next
请告诉我为什么它没有模板参数。
1个回答

28

这被称为“注入类名”,规则来自于[temp.local]:

像普通(非模板)类一样,类模板有一个“注入类名”(第9条)。注入类名可以用作模板名或类型名。当它与模板参数列表一起使用时, 作为模板参数为模板的模板参数或作为友元类模板声明的扩展类型说明符中的最后标识符时,它引用了类模板本身。否则,它等同于跟在模板名后面的类模板封装在<>中的模板参数的模板名

在类模板特化或部分特化的范围内,当注入类名被用作类型名时,它等同于跟在模板名后面的类模板特化或部分特化封装在<>中的模板参数的模板名。 [例子:

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
    };
};

这基本上是出于方便考虑,这样类内部的类名就指代类本身而不是可能与其名称相同的外部内容。对于类模板,如果您有一个很长的模板参数列表,这样做可以潜在地节省很多打字时间。


那么 Link<E>* next 和 Link* next 是等价的吗? - Makoto
2
@Makoto 在 template <typename E> class Link { ... }; 中,没错。 - Barry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接