V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Tony042
V2EX  ›  C++

关于 using declaration 在 C++类继承模板中的问题

  •  
  •   Tony042 · 2020-07-26 09:55:14 +08:00 · 1359 次点击
    这是一个创建于 1613 天前的主题,其中的信息可能已经有所发展或是发生改变。
    #include <iostream>
    using std::cout;
    using std::endl;
    
    template <typename T>
    class IteratorFacade
    {
    public:
        using Type = T;
    };
    
    template <typename T>
    class Iterator : public IteratorFacade<T>
    {
    public:
        using _Type = T;
        static Type test()
        {
            return 1;
        }
    };
    
    int main()
    {
        cout << Iterator<int>::test() << endl;
        return 0;
    }
    

    在以上代码中,MSVC 16.9 可以通过测试,GCC 10 不可以通过测试,在一个更复杂的 代码中,MSVC 和 GCC 均会因为同样原因无法通过编译。GCC 报错原因是 17:12: error: ‘Type’ does not name a type; did you mean ‘_Type’? 也就说Type这个类型并没有继承到 Iterator 类中,但是如果将 test()函数声明中的 Type 改成 Iterator::Type,两个编译器均可以通过编译,我想问下,为什么以上代码通不过编译呢?如果不用模板或者子类不用 using 上面代码均是可以正常编译运行的。

    3 条回复    2020-07-26 23:34:28 +08:00
    geelaw
        1
    geelaw  
       2020-07-26 10:45:55 +08:00
    因为 Type 不是依赖名称,它会在模板实例化之前解析。简单的解决方案是在 Derived 里面写

    using IteratorFacadeType = typename IteratorFacade<T>::Type;

    以免每次用这个类型的时候都要写一大串。
    Tony042
        2
    Tony042  
    OP
       2020-07-26 10:51:49 +08:00
    @geelaw 好的,刚才我也查了一下,确实是因为 Type 不是依赖名称的原因,谢谢大佬
    leimao
        3
    leimao  
       2020-07-26 23:34:28 +08:00 via iPhone
    MSVC 居然能编译通过我倒是很诧异。用 scope 是 best practice 。上面的这个例子如果是 multiple inheritance,每个 base class 都有 Type,那就有歧义了。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3035 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 14:26 · PVG 22:26 · LAX 06:26 · JFK 09:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.