代码来自C ++书籍,如下所示:
为什么这个公共成员Link * next没有typename参数?
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
。
请告诉我它没有模板参数的原因。
答案 0 :(得分:17)
这被称为“注入类名”。该规则具体来自[temp.local]:
与普通(非模板)类一样,类模板具有 inject-class-name (第9条)。 注入类 - 名称可用作模板名称或类型名称。当它与 template-argument-list 一起使用时, 作为模板模板参数的模板参数,或 elaborated-type-specifier 中的最终标识符 朋友类模板声明,它指的是类模板本身。否则,等同于 到 template-name 后面跟着
<>
中包含的类模板的模板参数。在类模板特化或部分特化的范围内,当注入类名时 用作类型名称,它等同于 template-name ,后跟类的 template-arguments &lt;&gt;中包含的模板特化或部分特化 [例如:
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]
这基本上是为了方便,因此类中的类名称引用类本身,而不是任何可能具有相同名称的外部名称。对于类模板,如果您有一个长模板参数列表,它可能会节省大量的输入。