2012-04-16 118 views
5

A.H为什么我不能使用模板类的父类变量?

template <typename T> 
class A 
{ 
    public: 
    int a; 
} 

b.h

template <typename T> 
class B : public A<T> 
{ 
    public: 
    int f(); 
} 

template <typename T> 
int B<T>::f() 
{ 
    int t; 
    t = this->a; //Okay 
    t = a //Error 
    return 0; 
} 

当我不使用this->为什么错误发生?

我可以用某种方法省略this->吗?

(我固定的一些错误)

+0

Joachim Pileborg给你答案。除此之外,所提供的代码还有其他一些问题妨碍了它的编译。 – Anonymous 2012-04-16 09:07:44

+0

这是实际的码?在类定义之后没有后缀分号,而int B :f()'的作用域运算符不正确,并且在错误行处没有分号。 – hmjd 2012-04-16 09:07:53

+0

哦,这只是一个打字错误。我修好了它。 – 2012-04-16 09:17:07

回答

11

有模板实例化(“两阶段名称查找”)两个阶段。

在第一阶段,所有非从属名称都被解析(查找)。在第二阶段,依赖名称被解析。

一个从属名称是依赖于模板参数的名称,例如:

template <typename T> 
void foo() { 
    x = 0; // <- Non-dependent, nothing in that refers to "T". 
       // Thus looked up in phase 1, therefore, an 'x' must be 
       // visible. 

    T::x = 0; // <- Dependent, because it depends on "T". 
       // Looked up in phase 2, which is when it must be visible. 
} 

现在,你写的:

t = this->a; //Okay 
t = a //Error 

这正是我所描述。在好的术语中,在阶段2, 中查找t,因为this取决于模板参数。

错误的术语在阶段1中查找,因为该名称中的任何内容都不依赖于模板参数。 但是在相1中,没有a是可见的,因为编译器不能在阶段1内省基类模板 ,因为模板可以专门和在实例化, 的点可以从主模板声明是远程的,另一个专业化 没有a,可能是可见的。

例子:

template <typename T> 
    struct Base { 
    }; 


    template <typename T> 
    struct Derived : Base<T> { 
     void foo() { 
      this->a = 0; // As is valid. `this->a` is looked up in phase 2. 
     } 
    }; 


    template <> struct Base<int> { 
     int a;    
    }; 


    int main() 
    { 
      // The following declarations trigger phase 2 lookup. 

      Derived<int> di; // valid, because a later specialized 
           // Base<int> is used and all symbols 
           // are resolved. 

      Derived<float> df; // not valid 
    } 

顺便说一句,我曾经写this-> is not only a matter of style我甚低频博客。

+0

从属名称是一个不依赖于模板参数的名称 - >依赖名称是一个取决于模板参数的名称:) – czxyl 2017-11-18 09:25:14

+0

@czxyl:差不多半年时间才能发现此错误:D感谢提示: ) – 2017-11-26 07:20:25

1

B是一个模板,因此它的名字是不相关的,因此必须抬起头来时,模板定义,而不是当它被实例化。但是,在定义模板时,从属名称是未知的(可能存在基类模板A迄今尚未见过的特化),编译器无法将未限定的名称解析为基类。

template <typename T> 
class B : public A<T> 
{ 
    public: 
    using A<T>::a; 
    int f(); 
}; 

另外请注意,您在那里打上类声明后失踪分号和行:您可以用A<T>::或用using声明把名字变成电流范围通过this->资格,由前缀它// Error评论。

+0

“从属名称不知道” - >这在C++的说法中没有意义。名称可能与否取决于,例如typename T,'A :: x'是一个独立的名字,'x'不是。作为程序员,“x”是一个依赖名称对你来说可能是有意义的,但从技术上讲,“x”不是一个依赖名称。 – 2012-04-16 09:42:39

+0

-1:“它的名字是不依赖的,因此必须查找” - >这是错误的。可以有依赖的成员名称。例如:http://ideone.com/zIa7k – 2012-04-16 09:47:07

+0

-1:'this->'与范围界定无关。 – 2012-04-16 09:48:58

相关问题