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

2020-07-26 09:55:14 +08:00
 Tony042
#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 上面代码均是可以正常编译运行的。

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

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

以免每次用这个类型的时候都要写一大串。
Tony042
2020-07-26 10:51:49 +08:00
@geelaw 好的,刚才我也查了一下,确实是因为 Type 不是依赖名称的原因,谢谢大佬
leimao
2020-07-26 23:34:28 +08:00
MSVC 居然能编译通过我倒是很诧异。用 scope 是 best practice 。上面的这个例子如果是 multiple inheritance,每个 base class 都有 Type,那就有歧义了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/693161

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX