考虑以下:
template<class> struct T
{
struct T1
{
struct T2
{
};
};
/*typename*/ T1::T2 m;
};
如果没有typename
,编译会失败,因为 T2 被认为是从属名称,因此不是类型。在查看了 C++17 草案标准 (N4659) 之后,我相信我已经确定了原因:
§ 17.6.2.1 ¶ 5
一个名称是当前实例化的成员,如果它是
- 一个非限定名称,当查找时,它指的是作为当前实例化的类或其非依赖基类的至少一个成员。
...
如果名称是当前实例化的成员,并且在查找时引用了作为当前实例化的类的至少一个成员,则该名称是当前实例化的依赖成员。
T1 是当前实例化的从属成员。T2 不是当前实例化的成员(它是 T1 的成员),
§ 17.6.2.1 ¶ 9.3
一个类型是依赖的,如果它是
......
- 一个嵌套类或枚举,它是当前实例化的依赖成员,
......
T1 是一个嵌套类,因此是一个依赖类型。
§ 17.6 ¶ 3
当qualified-id旨在引用不是当前实例化(17.6.2.1)成员的类型并且其nested-name-specifier引用依赖类型时,它应以关键字typename为前缀,形成一个类型名说明符。...
因此,typename
需要。
我的理解正确吗?如果是这样,这背后的理由是什么?除了嵌套在 T1 中的 T2 之外,查找如何T1::T2
找到任何东西?