【问题标题】:Nested classes are dependent types in class templates?嵌套类是类模板中的依赖类型?
【发布时间】: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


    【解决方案1】:

    是的,你是对的。

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

    template<class> struct T
    {
        struct T1
        {
            struct T2
            {
    
            };
        };
    
        void foo() {
            typename T1::T2 m;
        }
    };
    
    template<>
    struct T<void>::T1 {
        int T2;
    };
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-07
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      • 2011-02-25
      相关资源
      最近更新 更多