嵌套 class 是 class 模板中的依赖类型?

Nested classes are dependent types in class templates?

考虑以下几点:

template<class> struct T
{
    struct T1
    {
        struct T2
        {

        };
    };
    /*typename*/ T1::T2 m;
};

如果没有 typename,编译将失败,因为 T2 被认为是从属名称,因此不是类型。在查看了 C++17 标准草案 (N4659) 之后,我相信我已经确定了原因:

§ 17.6.2.1 ¶ 5

A name is a member of the current instantiation if it is
— An unqualified name that, when looked up, refers to at least one member of a class that is the current instantiation or a non-dependent base class thereof.
...
A name is a dependent member of the current instantiation if it is a member of the current instantiation that, when looked up, refers to at least one member of a class that is the current instantiation.

T1 是当前实例化的依赖成员。 T2 不是当前实例化的成员(它是 T1 的成员),

§ 17.6.2.1 ¶ 9.3

A type is dependent if it is
...
— a nested class or enumeration that is a dependent member of the current instantiation,
...

T1 是一个嵌套的 class,因此是一个依赖类型。

§ 17.6 ¶ 3

When a qualified-id is intended to refer to a type that is not a member of the current instantiation (17.6.2.1) and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename, forming a typename-specifier. ...

因此,需要typename

我的理解对吗?如果是这样,这背后的理由是什么? T1::T2 的查找怎么能找到除嵌套在 T1 中的 T2 之外的任何内容?

是的,你是对的。

在您的情况下,这无关紧要,因为您不可能在不实例化 m 的情况下专门化 T1(因为它是 class 成员)。但是你可以这样做,将 m 放在一个函数中:

template<class> struct T
{
    struct T1
    {
        struct T2
        {

        };
    };

    void foo() {
        typename T1::T2 m;
    }
};

template<>
struct T<void>::T1 {
    int T2;
};

如果 T1 不相关,您的代码可能会改变含义,因为 T2 将引用值而不是类型。