为什么派生模板类不能访问基模板类的标识符?
考虑:
template <typename T>
class Base
{
public:
static const bool ZEROFILL = true;
static const bool NO_ZEROFILL = false;
}
template <typename T>
class Derived : public Base<T>
{
public:
Derived( bool initZero = NO_ZEROFILL ); // NO_ZEROFILL is not visible
~Derived();
}
我无法使用 GCC g++ 3.4.4 (cygwin) 编译它.
I am not able compile this with GCC g++ 3.4.4 (cygwin).
在将这些转换为类模板之前,它们是非泛型的,派生类能够看到基类的静态成员.这是 C++ 规范要求的可见性损失还是我需要使用的语法更改?
Prior to converting these to class templates, they were non-generic and the derived class was able to see the base class's static members. Is this loss of visibility in a requirement of the C++ spec or is there a syntax change that I need to employ?
我知道 Base
的每个实例化都会有它自己的静态成员ZEROFILL
"和NO_ZEROFILL
",即 Base<float>::ZEROFILL
和 Base<double>::ZEROFILL
是不同的变量,但我并不在乎;常量是为了代码的可读性.我想使用静态常量,因为它在名称冲突方面比宏或全局更安全.
I understand that each instantiation of Base<T>
will have it's own static member "ZEROFILL
" and "NO_ZEROFILL
", that Base<float>::ZEROFILL
and Base<double>::ZEROFILL
are different variables, but i don't really care; the constant is there for readability of the code. I wanted to use a static constant because that is more safe in terms of name conflicts rather than a macro or global.
推荐答案
这对您来说是两阶段查找.
That's two-phase lookup for you.
Base<T>::NO_ZEROFILL
(所有大写标识符都是 boo,除了宏,顺便说一句)是一个依赖于 T
的标识符.
因为,当编译器第一次解析模板时,还没有替换 T
的实际类型,所以编译器不知道"Base
是什么.因此,它无法知道您假设在其中定义的任何标识符(编译器稍后才看到某些 T
的特殊化),并且您不能从定义的标识符中省略基类限定基类.
Base<T>::NO_ZEROFILL
(all caps identifiers are boo, except for macros, BTW) is an identifier that depends on T
.
Since, when the compiler first parses the template, there's no actual type substituted for T
yet, the compiler doesn't "know" what Base<T>
is. So it cannot know any identifiers you assume to be defined in it (there might be a specialization for some T
s that the compiler only sees later) and you cannot omit the base class qualification from identifiers defined in the base class.
这就是为什么你必须编写Base
(或this->NO_ZEROFILL
).这告诉编译器 NO_ZEROFILL
是基类中的东西,它依赖于 T
,并且它只能在模板被实例化时验证它.因此,它会在不尝试验证代码的情况下接受它.
该代码只能在稍后通过为 T
提供实际参数来实例化模板时进行验证.
That's why you have to write Base<T>::NO_ZEROFILL
(or this->NO_ZEROFILL
). That tells the compiler that NO_ZEROFILL
is something in the base class, which depends on T
, and that it can only verify it later, when the template is instantiated. It will therefore accept it without trying to verify the code.
That code can only be verified later, when the template is instantiated by supplying an actual parameter for T
.
相关文章