4

关于继承的成员变量的可见性的编译器错误使我感到困惑。我将其简化为这个最小、完整且可验证的示例:

#include <iostream>

template <typename T> class Base {
    protected:
        T m_value = T{};
};

template <typename T> class Derived : public Base<T> {
    public:
        void Foo() { std::cout << m_value; };
};

int main() {
    Derived<int> d;
    d.Foo();
}

MSVC 报告:

Source.cpp(10,35): error C2065: 'm_value': undeclared identifier
Source.cpp(10,35): error C3861: 'm_value': identifier not found

我很惊讶: Derived<T>应该继承m_valueBase<T>并且应该可以访问,因为它受到保护。

我尝试进一步减少问题:Base<T>用非模板类替换并将其声明m_value为 int works。保留Base<T>为模板类并制作Derived非模板类(派生自Base<int>也可以。问题仅在于两者都是模板时。

我发现了其他类似标题的 StackOverflow 问题,但都不是这个问题。这些问题通常涉及阴影或语法错误。

我尝试了 Compiler Explorer (godbolt.org) 来查看 Clang 和 gcc 是否同意 MSVC。 Clang 10也报告错误,gcc 10.2也是如此。奇怪的是,编译器资源管理器上的MSVC 19.24可以愉快地编译代码而没有错误。我本地的 MSVC 更新:19.26。所以目前主流 C++ 编译器版本的共识是代码是错误的。

当基类和派生类都是模板实例时,有人可以解释为什么派生类看不到基类的受保护成员变量吗?

4

0 回答 0