2012-04-16 121 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

相關問題