C++ 中的 Typename 关键字
Suraj P
2023年10月12日
本文将讨论 C++ 中的关键字 typename
。
要理解关键字 typename
的意义,我们需要了解 qualified
和 dependent
名称的关键概念。
C++ 中的限定名和非限定名
限定名称指定范围。让我们看一个例子来更好地理解它。
#include <bits/stdc++.h>
int main() { std::cout << "Hello world!" << std::endl; }
对 cout
和 endl
的引用在这里是限定名称。但是,如果我们使用 using
声明将它们都带入范围,即 using namespace std
并且仅使用 cout
本身,它们将成为 unqualified
名称,因为它们缺少 std::
。
C++ 中的从属和非从属名称
从属名称是依赖于模板
参数的名称。
让我们看一个示例代码以更好地理解它。
template <class T>
class MyClass {
int i;
vector<int> vi;
vector<int>::iterator vitr;
T t;
vector<T> vt;
vector<T>::iterator viter;
}
前三个声明被称为非依赖名称,因为它们的类型在模板声明时是已知的。
而如果我们查看第二组声明,T
、vector<T>
和 vector<T>::iterator
是依赖名称,因为它们的类型直到实例化点才知道,因为它们依赖于模板参数 T
。
在 C++ 中使用 typename
关键字
作为一般规则,在引用类型的限定名称或从属名称之前必须使用 typename
关键字。
因此,引入关键字 typename
来指定后面的标识符是类型而不是静态成员变量。
class A {
public:
typedef int myPtr;
};
template <class T>
class myClass {
public:
typename T::SubType* myPtr;
}
在上面的代码中,typename
关键字告诉编译器 SubType
是类 T
的类型,这意味着指针 myptr
是 T::SubType
的类型。
如果没有 typename
关键字,SubType
将被视为静态成员,编译器会将其评估为 T
类型的 SubType
与指针 myptr
的乘积。
T::SubType * myptr //compiler will think it's multiplication
如果我们在上面的代码中不使用关键字 typename
,会导致编译时错误,因为编译器不知道 T::SubType
是引用类型名还是引用的静态成员 T
。