Tony042
V2EX  ›  C++

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

By Tony042 at 2020 年 7 月 26 日 · 2184 次点击
#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 年 7 月 26 日
因为 Type 不是依赖名称,它会在模板实例化之前解析。简单的解决方案是在 Derived 里面写

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

以免每次用这个类型的时候都要写一大串。
Tony042
   2
Tony042  
OP
   2020 年 7 月 26 日
@geelaw 好的,刚才我也查了一下,确实是因为 Type 不是依赖名称的原因,谢谢大佬
leimao
   3
leimao  
   2020 年 7 月 26 日 via iPhone
MSVC 居然能编译通过我倒是很诧异。用 scope 是 best practice 。上面的这个例子如果是 multiple inheritance,每个 base class 都有 Type,那就有歧义了。
© 2026 V2EX · 57ms · 3.9.8.5