考虑:

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的)。

不能编译此

在此之前将这些类模板,它们是非通用的和派生类能够看到基类的静态成员。是知名度的这种损失在C ++规范的要求,或是否有语法的变化,我需要使用?

据我所知,Base<T>的每个实例都会有它自己的静态成员“ZEROFILL”和“NO_ZEROFILL”,即Base<float>::ZEROFILLBase<double>::ZEROFILL是不同的变量,但我真的不关心;常量是有代码的可读性。我想用一个静态常量,因为在名称冲突的条款,而不是宏观或全球更加安全。

有帮助吗?

解决方案

这是给你的两阶段查找。

Base<T>::NO_ZEROFILL(全部大写标识符是嘘声,除了宏,顺便说一句)是取决于T的标识符。结果 因为,当编译器首先分析模板,也没有实际的类型T取代的是,编译器并不“知道”什么是Base<T>。因此,它可以不知道你承担它被定义的任何标识符(有可能是一些Ts,编译器只是后来看到一个专业化),你不能省略从基类中定义的标识符的基类资格。

这就是为什么你必须写Base<T>::NO_ZEROFILL(或this->NO_ZEROFILL)。这告诉NO_ZEROFILL东西在基类,它依赖于T,而且它只能稍后再验证它,当模板实例化编译器。因此,它会接受它,但不尝试验证码。结果 该代码只能被后经核实,当模板通过为T实际参数实例化。

其他提示

您遇到的问题是由于对相关的基类名称查找规则。 14.6 / 8具有:

  

当寻找一个名称的模板中的定义中使用的声明,通常的查找规则(3.4.1,   3.4.2)用于非依赖的名字。名字依赖于模板参数的查找是   推迟直到实际模板参数是已知的(14.6.2)。

(这不是真正“2阶段查找” - 见下文的那个的解释)

在点约14.6 / 8是尽可能的编译器而言在你的例子NO_ZEROFILL是一个标识符,并且不依赖于模板参数。因此,它被查找按照一般规则在3.4.1和3.4.2。

此正常查找没有内部Base<T>搜索等NO_ZEROFILL仅仅是一个未声明的标识符。 14.6.2 / 3具有:

  

在一个类模板或模板类中的成员的定义,如果一个基类类模板的   依赖于模板的参数,不合格的名称查找期间不检查的基类范围   无论是在类模板或构件或定义的类模板的实例化期间,点   或构件。

当你在本质上与NO_ZEROFILL资格Base<T>::你是从一个非从属名称为依赖一个改变它,当你做,你耽误了查找,直到模板实例。

<强>边注:什么是2-阶段查找

void bar (int);

template <typename T>
void foo (T const & t) {
  bar (t);
}


namespace NS
{
  struct A {};
  void bar (A const &);
}


int main ()
{
  NS::A a;
  foo (a);
}

在上面的例子如下编译。编译器解析foo的功能体和看到,有一个呼叫到bar具有依赖参数(即,一个是依赖于模板的参数)。此时编译器查找栏按3.4.1,这是“第1阶段查找”。该查找会发现功能void bar (int)和存储与因呼叫,直到后来。

当模板然后实例化(如从main呼叫的结果),编译器然后执行在参数的范围的附加的查找,这是在“第2阶段的查找”。这种情况下,其导致在寻找void NS::bar(A const &)

编译器有两个重载bar并在它们之间进行选择,在上述情况下主叫void NS::bar(A const &)

看起来编译好的在VS 2008你试过:

public:
    Derived( bool initZero = Base<T>::NO_ZEROFILL );

试试这个程序

#include<iostream>
using namespace std;
template <class T> class base{
public:
T x;
base(T a){x=a;}
virtual T get(void){return x;}
};
template <class T>
class derived:public base<T>{
public:
derived(T a):base<T>(a){}
T get(void){return this->x+2;}
};
int main(void){
base<int> ob1(10);
cout<<ob1.get()<<endl;
derived<float> ob(10);
cout<<ob.get();
return 0;
}

T get(void){return this->x+2;}系U还可以使用范围分辨率(::)运算符。例如,尝试用替换行

T get(void){return base<T>::x+2;}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top