关于继承的成员变量的可见性的编译器错误使我感到困惑。我将其简化为这个最小、完整且可验证的示例:
#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_value
自 Base<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++ 编译器版本的共识是代码是错误的。
当基类和派生类都是模板实例时,有人可以解释为什么派生类看不到基类的受保护成员变量吗?