[英]Confused about C++ nested dependent type name
Effective C++ told me that I'd better use typename
when encountered nested dependent type name. 有效的C ++告诉我,当遇到嵌套的依赖类型名称时,我最好使用
typename
。
The following example code is easy to understand: 以下示例代码很容易理解:
template <typename ElementType>
class BST {
private:
class LinkNode {
public:
ElementType data;
LinkNode *left, *right;
explicit LinkNode() {}
};
public:
void some_func();
}
template <typename ElementType>
void BST<ElementType>::some_func() {
// or `using NodePtr = typename BST<ElementType>::LinkNode *;`
typedef typename BST<ElementType>::LinkNode * NodePtr;
...
}
However, after I added using aliases in the template class BST, it seemed that keyword typename
is not neccessary anymore. 但是,在我在模板类BST中添加别名后,似乎不再需要关键字
typename
。
Here you can see: 在这里你可以看到:
template <typename ElementType>
class BST {
private:
class LinkNode {
public:
ElementType data;
LinkNode *left, *right;
explicit LinkNode() {}
};
using NodePtr = LinkNode *; // the only difference between these two code blocks
public:
void some_func();
}
template <typename ElementType>
void BST<ElementType>::some_func() {
// typename is not neccessary here!
BST<ElementType>::NodePtr ptr;
...
}
Does anyone could figure out that? 有人能搞清楚吗?
That effect is not directly tied to type alias through using
, it's a result of name lookup for member of the current instantiation. 该效果并未通过
using
直接与类型别名相关联,它是当前实例化成员的名称查找结果。
Inside BST
both BST
and BST<ElementType>
expression refer to the current instantiation and the members of it can be found without the need of the prefix typename
you could do: 在
BST
内部, BST
和BST<ElementType>
表达式引用当前实例化,并且可以在不需要您可以执行的前缀typename
情况下找到它的成员:
template <typename ElementType>
void BST<ElementType>::some_func() {
BST::NodePtr ptr; // or
BST<ElementType>::LinkNode * ptr2;
}
resulting in the same thing. 导致同样的事情。 But now let assume that
some_func
is also a template member function defined as: 但现在让我们假设
some_func
也是一个模板成员函数,定义如下:
template <typename ElementType>
struct BST {
class LinkNode { /*...*/ };
using NodePtr = LinkNode *;
template <typename T>
void some_func();
};
template <typename ElementType>
template <typename T>
void BST<ElementType>::some_func() {
BST<T>::NodePtr ptr; // (1)
BST<T>::LinkNode * ptr2 // (2)
}
Now neither (1) nor (2) will compile because B<T>
is no longer the current instantiation, hence in these cases you need typename
. 现在,(1)和(2)都不会编译,因为
B<T>
不再是当前的实例化,因此在这些情况下你需要typename
。
The relevant part of the standard [temp.res]/7
: 标准
[temp.res]/7
的相关部分:
Within the definition of a class template or within the definition of a member of a class template following the declarator-id, the keyword typename is not required when referring to the name of a previously declared member of the class template that declares a type or a class template.
在类模板的定义内或在declarator-id之后的类模板成员的定义内,当引用声明类型或类的模板的先前声明的成员的名称时,不需要关键字typename。类模板。 [...]
[...]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.