【发布时间】:2018-12-08 21:41:44
【问题描述】:
考虑以下几点:
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-specifier。 ...
因此,需要typename。
我的理解正确吗?如果是这样,这背后的理由是什么? T1::T2 的查找怎么能找到嵌套在 T1 中的 T2 以外的任何东西?
【问题讨论】:
标签: c++ templates c++17 dependent-name